【问题标题】:Interprocess Mutex In PerlPerl 中的进程间互斥锁
【发布时间】:2010-11-05 17:58:28
【问题描述】:

我有一个在 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)?信号量只能初始化一次。

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

【问题讨论】:

  • 为什么会有数千个临时文件?如果您打算使用一个信号量,则只需使用一个文件。
  • 我将使用每个客户基本的信号量。因为一个客户可以一次发送多个 HTTP 请求。

标签: perl ipc semaphore


【解决方案1】:

添加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;
}

【讨论】:

  • 不使用number(10023, 10024)来识别信号量的唯一性,可以使用string (helloworld, goodbyeworld)吗?
  • 您可能应该使用的是 ftok(linux.die.net/man/3/ftok),但是请注意,只使用了 8 位 proj_id
  • 谢谢!一旦我可以访问机器,我会尝试一下。一件事是,我什么时候应该调用 $sem->remove?最初,我计划在 END {#inrease 计数器中将其调用回 1。 #remove semaphore from system???} 块。但是,如果我从系统中删除信号量,而有另一个进程等待信号量的锁定,是否有任何副作用(互斥会中断,突然所有等待的进程都能够获取资源)。是不是,我应该忽略“删除”电话吗?这会导致系统资源泄漏吗?
  • 我会使用一个打开信号量的计划任务,然后使用 stat 检查 sem 的 otime(最后一个 semop 时间)来决定是否应该删除它。 re:删除行为,semctl 手册页 (linux.die.net/man/2/semctl) 声明所有等待进程将被唤醒,semop 调用返回错误(在 perl 情况下为 false)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-10
  • 2021-08-13
  • 2011-09-22
  • 1970-01-01
  • 2013-08-09
  • 2022-08-21
  • 1970-01-01
相关资源
最近更新 更多