Perl flock on Linux:如果许多进程等待打开锁定文件会怎么样?

时间:2016-02-09 16:28:39

标签: linux perl locking

如果许多进程等待打开一个独占锁定的文件,当它被释放时会发生什么?

我希望只有一个需要open才能成功再次打开文件的进程,但似乎不是这样......

我确实阅读了linux flock系统调用的文档(以及Perl的flock()函数),但我找不到该用例的任何内容......

这是我的用例详细说明:
一些CGI perl进程在LAN上调用一个中央服务,这是非常繁重和缓慢的,并且如果一次由一个客户端调用则表现更好。 CGI请求可能很多(例如50~60)并发,因此我使用flock机制作为信号量,以便CGI进程在调用中央服务之前等待,一个在一段时间。

这是我用来实现信号量的(简化)代码:

open($LOCK, "+>" . "/tmp/semaphore.lock") or die("Can't open semaphore ($!)");
flock($LOCK, LOCK_EX) or die ("Can't lock semaphore ($!)");

# <CALL THE SLOW SERVICE>

flock($LOCK, LOCK_UN) or die("Can't unlock semaphore ($!)");
close($LOCK);

我期望的流程是:

CGI process A opens semaphore
CGI process A locks semaphore
CGI process A calls service
CGI process B opens semaphore
CGI process C opens semaphore
CGI process D opens semaphore
CGI process A unlocks semaphore
CGI process B locks semaphore
CGI process B calls service
CGI process B unlocks semaphore
CGI process C locks semaphore
...

但是,我观察到的流程是:

CGI process A opens semaphore
CGI process A locks semaphore
CGI process A calls service
CGI process B opens semaphore
CGI process C opens semaphore
CGI process D opens semaphore
CGI process A unlocks semaphore
CGI process B locks semaphore
CGI process B calls service
CGI process C locks semaphore   (!)
CGI process C calls service     (!)
CGI process D locks semaphore   (!)
CGI process D calls service     (!)
CGI process B unlocks semaphore
...

答案(如果可能的话)应该优先考虑对当前代码进行尽可能少修改的解决方案,因为它在相当长的时间内处于生产阶段,因此:变化越少,越好......: - )

1 个答案:

答案 0 :(得分:1)

在任何给定时间,只有一个进程可以拥有独占锁。

因此,以下其中一项应适合您:

  • 您要锁定的文件位于NFS设备上。 flock不支持这些。
  • 您描述的对flock的调用发生在同一进程中。 flock不能用于排除同一进程的线程。
  • 锁已被释放。请记住,解锁可能发生在分叉过程中。