羊群锁定顺序?

发布于 2024-08-28 15:20:03 字数 655 浏览 8 评论 0原文

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

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

im using a simple test script from
http://www.tuxradar.com/practicalphp/8/11/0
like this

<?php
$fp = fopen("foo.txt", "w");
if (flock($fp, LOCK_EX)) {
    print "Got lock!\n";
    sleep(10);
    flock($fp, LOCK_UN);
}

i opened 5 shell's and executed the script one after the other
the scripts block until the lock is free'ed and then continues after released

im not really interessted in php stuff, but my question is:
anyone knows the order in which flock() is acquired?

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?

is there a simple deterministic order, like a queue or does the kernel 'just' pick one by "more advanced rules"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

七堇年 2024-09-04 15:20:03

如果有多个进程等待排它锁,则不指定哪个进程首先成功获取它。不要依赖任何特定的顺序。

话虽如此,当前的内核代码按照它们阻塞的顺序唤醒它们。此注释位于 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,依此类推。

If there are multiple processes waiting for an exclusive lock, it's not specified which one succeeds in acquiring it first. Don't rely on any particular ordering.

Having said that, the current kernel code wakes them in the order they blocked. This comment is in 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.
 */

If you want to have a set of processes run in order, don't use flock(). Use SysV semaphores (semget() / semop()).

Create a semaphore set that contains one semaphore for each process after the first, and initialise them all to -1. For every process after the first, do a semop() on that process's semaphore with a sem_op value of zero - this will block it. After the first process is complete, it should do a semop() on the second process's semaphore with a sem_op value of 1 - this will wake the second process. After the second process is complete, it should do a semop() on the third process's semaphore with a sem_op value of 1, and so on.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文