羊群锁定顺序?

时间:2010-04-14 09:07:27

标签: linux flock

我正在使用一个简单的测试脚本 http://www.tuxradar.com/practicalphp/8/11/0 像这样

<?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?

是否有一个简单的确定性顺序,如队列,或内核“只是”通过“更高级的规则”选择一个?

1 个答案:

答案 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,依此类推。