Межпроцессный Mutex In Perl - PullRequest
3 голосов
/ 25 июня 2009

У меня есть программа Perl CGI, которая выполняется под mod_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. Как я могу заставить Code (1) создавать новый семафор ТОЛЬКО тогда, когда семафор, если идентификатор 10023 никогда ранее не создавался ни тем же процессом, ни другими процессами?
  2. Как выполнить код (2) ТОЛЬКО при первом создании семафора с идентификатором 10023? Семафор должен быть инициализирован только ОДИН РАЗ.

Другой подход заключается в создании пустого файла для блокировки. Тем не менее, это будет иметь тысячи временных файлов. текст ссылки

1 Ответ

5 голосов
/ 25 июня 2009

Добавление флага 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;
}
...