2009-06-25 7 views
1

나는 mod_perl 하에서 실행되는 Perl CGI 프로그램을 가지고있다. 프로그램 내에서 리소스가 동시에 여러 프로세스에 액세스하지 못하도록하고 싶습니다.펄에서 프로세스 간 뮤텍스

# Semaphore Initialization Code 
# 10023 is unique id, and this id will be same across different apache process. 
# 1, Only one semaphore being created. 
# 0722, as all process will be execute under apache account. Hence, they will all having '7' privilege. 
my $sem = new IPC::Semaphore(10023, 1, 0722 | IPC_CREAT); # Code(1) 
# Set 0th (one and only one) semaphore's value to 1, As I want to use this semaphore as mutex. 
$sem->setval(0, 1);          # Code(2) 

문제는 :

  1. 가 어떻게 같은 프로세스 또는 다른 프로세스에 의해 하나, 코드 (1) 세마포어가 10023 ID가 이전에 생성되고 있지 않을 경우에만 새로운 세마포어를 생성 할 수 있습니다 ?
  2. 10023 ID를 가진 세마포어를 처음 만들 때만 코드 (2)를 실행할 수 있습니까? 세마포어는 한 번만 초기화되어야합니다.

또 다른 방법은 잠금 목적으로 빈 파일을 만드는 것입니다. 그러나 이로 인해 수천 개의 임시 파일이 생깁니다. IPC_EXCL 플래그를 추가 link text

+1

왜 수천? 하나의 세마포어를 사용하려면 하나의 파일 만 사용하십시오. – ysth

+0

고객마다 기본 세마포어를 사용하겠습니다. 한 고객이 한 번에 여러 개의 HTTP 요청을 보낼 수 있으므로 가능합니다. –

답변

4

새로운 세마포어를 만들거나 실패 중 하나를 기본 semget됩니다. 이것을 사용하여 원하는 효과를 얻을 수 있습니다.

이 당신을 위해 작동합니다 : 임시 파일의

#Attempt to create (but not get existing) semaphore 
my $sem = IPC::Semaphore->new(10023, 1, 0722 | IPC_CREAT | IPC_EXCL); 
if ($sem) { 
    #success, semaphore created, proceed to set. 
    print "new semaphore\n"; 
    $sem->setval(0, 1); 
} 
else { 
    #obtain the semaphore normally 
    print "existing semaphore\n"; 
    $sem = IPC::Semaphore->new(10023, 1, 0722); #no IPC_CREAT here 
    die "could not obtain semaphore?" unless $sem; 
} 
+0

숫자 (10023, 10024)를 사용하여 세마포어의 고유성을 식별하는 대신 string (helloworld, goodbyeworld)을 사용할 수 있습니까? –

+0

아마도 ftok (http://linux.die.net/man/3/ftok)를 사용해야하지만, 8 비트의 proj_id 만 사용됩니다. – Hasturkun

+0

고마워요! 일단 기계에 접속하면 시험해 보겠습니다. 한 가지는, $ sem-> remove를 호출해야 할 때입니다. 처음에 나는 END에서 호출 할 계획이다. 시스템에서 #remove semaphore?} 블록. 그러나 세마포어 잠금을 기다리는 다른 프로세스가있는 동안 시스템에서 세마포를 제거하면 부작용이 발생합니다 (상호 배타가 중단되어 갑자기 모든 프로세스가 리소스를 확보 할 수 있음). 내가 '제거'전화를 무시하지 않을까요? 이로 인해 시스템 리소스가 유출됩니까? –