Perl中的进程间互斥

Perl中的进程间互斥,perl,ipc,semaphore,Perl,Ipc,Semaphore,我有一个在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 apach

我有一个在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)
问题是:

  • 如果10023 id以前从未由同一进程或其他进程创建过,那么如何使代码(1)仅在信号量出现时创建新信号量
  • 如何仅在第一次使用10023 id创建信号量时执行代码(2)?信号量只能初始化一次
  • 另一种方法是为锁定目的创建一个空文件。然而,这最终会产生数千个临时文件。

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

    为什么有数千个临时文件?如果您计划使用一个信号量,您只需要使用一个文件。我将使用每个客户基本的信号量。由于一个客户可以一次发送多个HTTP请求。我们可以使用字符串(helloworld,goodbyeworld)来标识信号量的唯一性,而不是使用数字(10023,10024)来标识信号量的唯一性吗?您可能应该使用的是ftok(),但是请注意,只有8位的proj_id用于hanks!我一接触到这台机器就会试一下。一件事是,我什么时候打电话给你?最初,我计划在{#将计数器返回到1。#从系统中删除信号量???}块末尾调用它。然而,如果我在有另一个进程等待信号量锁定时从系统中移除信号量,是否有任何副作用(互斥将中断,突然所有等待的进程都能够抓住资源)。不是,我应该忽略“删除”呼叫吗?这会导致系统资源泄漏吗?我会使用一个计划任务打开信号量,然后使用stat检查sem的otime(上次semop时间)来决定是否应该删除它。re:remove behavior,semctl manpage()声明将唤醒所有等待的进程,semop调用返回一个错误(在perl情况下为false)