2009-06-25 48 views
1

我有一個Perl CGI程序,在mod_perl下執行。在程序中,我想阻止資源同時被多個進程訪問。Perl中的進程間互斥

# 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. 我怎樣才能執行代碼(2)只有我第一次創建10023 id的信號量?一次信號量只能被初始化。

另一種方法是爲鎖定目的創建一個空文件。但是,這最終會有成千上萬的臨時文件。 link text

+1

爲什麼成千上萬的臨時文件?如果您打算使用一個信號量,則只需使用一個文件。 – ysth 2009-06-25 06:13:05

+0

我將使用每個客戶基本的信號量。由於一個客戶可能一次發送多個HTTP請求。 – 2009-06-25 06:36:30

回答

4

添加IPC_EXCL標誌會導致底層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; 
}