【问题标题】:flock locking order?羊群锁定顺序?
【发布时间】:2011-02-07 19:57:36
【问题描述】:

我使用了一个简单的测试脚本 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?

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

【问题讨论】:

    标签: linux flock


    【解决方案1】:

    如果有多个进程在等待一个独占锁,不指定哪个进程先成功获取。不要依赖任何特定的顺序。

    话虽如此,当前的内核代码会按照它们阻塞的顺序唤醒它们。这条评论在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()sem_op 值为 1 - 这将唤醒第二个进程。第二个进程完成后,它应该在第三个进程的信号量上执行semop()sem_op 值为 1,依此类推。

    【讨论】:

    • 我知道您可能知道如何按特定顺序同步进程?如果没有其他方法生病不得不使用flock
    • @John Doe:是的,使用 SysV 信号量。查看我的答案的更新。
    • fs/locks.c flock 使用什么?
    • @JohnBachir:是的。
    • @caf 在我的实验中,flock 没有提供公平的队列。但也许只有在同一程序内部使用 locks.c 设施时才能实现公平? code.jjb.cc/linux-flock-does-not-provide-fair-locking
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 2012-12-30
    • 1970-01-01
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多