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. ID が 10023 のセマフォを初めて作成するときにのみ Code(2) を実行するにはどうすればよいですか? セマフォは 1 回だけ初期化されます。

もう 1 つの方法は、ロック用に空のファイルを作成することです。ただし、これにより、最終的に何千もの一時ファイルが作成されます。 リンクテキスト

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 に答える