当必须通过文件系统同步程序(shell脚本)时,我发现基于flock
的解决方案为recommended(也应该有效on NFS)。在脚本(来自http://linux.die.net/man/1/flock)中使用的规范示例是:
(
flock -s 200
# ... commands executed under lock ...
) 200>/var/lock/mylockfile
我不明白为什么整个构造确保原子性。特别是,我想知道在例如flock -s 200
和200>/var/lock/mylockfile
执行的顺序bash
执行这些代码行。这个订单是保证/确定性的吗?我理解它的方式,如果这个成语应该起作用,那么必须是确定性的。但是由于子进程是在子进程中生成的,所以我不明白这两个进程是如何同步的。我只看到这两个命令之间的竞争条件。
如果有人能让我对此消失感到困惑并理解为什么这个结构可以用来安全地同步进程,我将不胜感激。
同时,如果有人知道,我会感兴趣的是选择一些任意文件描述符(例如示例中的200
)是多么安全,特别是在大型NFS文件的上下文中有许多客户的系统。
答案 0 :(得分:5)
在子shell中执行任何命令之前,必须评估子shell (...) 200>/var/lock/mylockfile
的整个I / O上下文 - 并完成I / O重定向,因此重定向总是先于flock -s 200
。想想子shell是否将其标准输出传送到另一个命令;必须在创建子shell之前创建该管道。这同样适用于文件描述符200重定向。
文件描述符编号的选择确实无关紧要 - 除了建议不要使用文件描述符0-2(标准输入,输出,错误)。文件名很重要;不同的进程可以使用不同的文件描述符;只要名字达成一致,就应该没问题。