3

我有一个在 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. 如果以前从未创建过 10023 id(无论是由同一进程还是其他进程),我如何才能使 Code(1) 仅在信号量时创建一个新的信号量?
  2. 如何仅在第一次创建具有 10023 id 的信号量时执行 Code(2)?信号量只能初始化一次。

另一种方法是创建一个空文件用于锁定目的。但是,这最终将拥有数千个临时文件。 链接文本

4

1 回答 1

6

添加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;
}
于 2009-06-25T08:07:04.417 回答