Linux并发脚本与互斥体

在我的Linux服务器上,我需要同步BASH和PHP中编写的多个脚本,以便只有其中一个脚本能够启动系统关键的作业,这是一系列BASH / PHP命令,由两个或更多脚本同时执行。 从我在C ++multithreading方面的经验来看,我熟悉互斥体的概念,但是如何为一堆在单独进程中运行的脚本实现互斥体,当然,这些脚本不是用C ++编写的?

那么记住的第一个解决scheme就是确保每个脚本最初创build一个“locking标志”文件,让其他脚本知道该作业是“locking的”,然后在作业完成后删除该文件。 但是,正如我所看到的那样,文件写入读取操作必须是完全primefaces的,才能使此方法以100%的概率工作,同样的要求也适用于任何其他同步方法。 我很确定文件写入/读取操作不是primefaces的,至less在所有现有的Linux / Unix系统中都不是primefaces的。

那么同步BASH PHP脚本的最灵活可靠的方法是什么?

我不是一个PHP程序员,但文档说它提供了一个可以使用的便携版本的flock 。 第一个示例片段看起来非常接近你想要的。 尝试这个:

 <?php $fp = fopen("/tmp/lock.txt", "r+"); if (flock($fp, LOCK_EX)) { // acquire an exclusive lock // Do your critical section here, while you hold the lock flock($fp, LOCK_UN); // release the lock } else { echo "Couldn't get the lock!"; } fclose($fp); ?> 

请注意,默认情况下, flock等待,直到它可以获得锁定。 你可以使用LOCK_EX | LOCK_NB LOCK_EX | LOCK_NB如果你希望在程序的另一个副本已经在运行的情况下立即退出。

使用名称“/tmp/lock.txt”可能是一个安全漏洞(我不想认真考虑是否真的是这样),所以你应该选择一个只能被你的程序写入的目录。

你可以使用flock来自动锁定你的标志文件。 -e选项是获取排他锁。

从手册页:

默认情况下,如果无法立即获取锁定,则会等待锁定。

所以如果你所有的bash / php脚本都试图锁定文件,只有一个可以成功获取它,其余的将等待锁定。

如果你不想等,那就用-w超时。

在Bash中基于fuser的锁(它保证没有两个进程同时访问受保护的资源,但即使没有进程访问资源,也可能导致负的锁定尝试,但几乎不可能):

 #!/bin/bash set -eu function mutex { local file=$1 pid pids exec 8>>"$file" { pids=$(/sbin/fuser -f "$file"); } 2>&- 9>&- for pid in $pids; do [[ $pid = $$ ]] && continue exec 8>&- return 1 # locked by other pid done }