<?php
$fp = fopen("foo.txt", "w");
if (flock($fp, LOCK_EX)) {
print "Got lock!\n";
sleep(10);
flock($fp, LOCK_UN);
}
我打开了5个shell并一个接一个地执行了脚本 脚本阻塞,直到锁定被释放,然后在释放后继续
我不是真的在PHP的东西,但我的问题是: 谁知道flock()的获取顺序?
e.g.
t0: process 1 lock's
t1: process 2 try_lock < blocking
t2: process 3 try_lock < blocking
t3: process 1 releases lock
t4: ?? which process get's the lock?
是否有一个简单的确定性顺序,如队列,或内核“只是”通过“更高级的规则”选择一个?
答案 0 :(得分:8)
如果有多个进程在等待独占锁定,则不会指定哪个进程首先成功获取它。不要依赖任何特定的订购。
话虽如此,当前的内核代码按照它们阻止的顺序唤醒它们。此评论位于fs/locks.c
:
/* Insert waiter into blocker's block list.
* We use a circular list so that processes can be easily woken up in
* the order they blocked. The documentation doesn't require this but
* it seems like the reasonable thing to do.
*/
如果要按顺序运行一组进程,请不要使用flock()
。使用SysV信号量(semget()
/ semop()
)。
创建一个信号量集,其中包含每个进程在第一个之后的一个信号量,并将它们全部初始化为-1。对于第一个之后的每个进程,对该进程的信号量semop()
执行sem_op
值为零 - 这将阻止它。在第一个过程完成后,它应该对semop()
值为1的第二个进程的信号量执行sem_op
- 这将唤醒第二个进程。第二个过程完成后,它应该在semop()
值为1的第三个进程的信号量上执行sem_op
,依此类推。