羊群锁定顺序?
我使用一个简单的测试脚本 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果有多个进程等待排它锁,则不指定哪个进程首先成功获取它。不要依赖任何特定的顺序。
话虽如此,当前的内核代码按照它们阻塞的顺序唤醒它们。此注释位于
fs/locks.c
中:如果您希望一组进程按顺序运行,请不要使用
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
: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 asem_op
value of zero - this will block it. After the first process is complete, it should do asemop()
on the second process's semaphore with asem_op
value of 1 - this will wake the second process. After the second process is complete, it should do asemop()
on the third process's semaphore with asem_op
value of 1, and so on.