我想并行运行多个Bash shell脚本。但是,我想避免比赛条件。我可以为此目的使用哪些真正的 Unix命令,我该如何使用它们?
我想并行运行多个Bash shell脚本。但是,我想避免比赛条件。我可以为此目的使用哪些真正的 Unix命令,我该如何使用它们?
Answers:
如果lockfile
您的系统上未安装,mkdir
则将执行此工作:这是一个原子操作,如果目录已经存在,则失败(只要您不添加-p
命令行开关)。
create_lock_or_wait () {
path="$1"
wait_time="${2:-10}"
while true; do
if mkdir "${path}.lock.d"; then
break;
fi
sleep $wait_time
done
}
remove_lock () {
path="$1"
rmdir "${path}.lock.d"
}
#!/bin/bash
# Makes sure we exit if flock fails.
set -e
(
# Wait for lock on /var/lock/.myscript.exclusivelock (fd 200) for 10 seconds
flock -x -w 10 200
# Do stuff
) 200>/var/lock/.myscript.exclusivelock
这样可以确保“(”和“)”之间的代码一次仅由一个进程运行,并且该进程确实等待锁定的时间太长。
lockf(1)
。
lockf(1)
但是,它不能以本示例中使用的方式工作。它不能以文件描述符号作为参数。
lockfile(1)看起来不错,尽管要注意它是procmail软件包的一部分,但您可能尚未在计算机上安装它。这是一个非常流行的软件包,如果尚未安装,则应为您的系统打包。我检查过的四个系统中的三个拥有它,另一个拥有它。
使用它很简单:
#!/bin/sh
LOCKFILE=$HOME/.myscript/lock
mkdir -p `dirname $LOCKFILE`
echo Waiting for lock $LOCKFILE...
if lockfile -1 -r15 $LOCKFILE
then
# Do protected stuff here
echo Doing protected stuff...
# Then, afterward, clean up so another instance of this script can run
rm -f $LOCKFILE
else
echo "Failed to acquire lock! lockfile(1) returned $?"
exit 1
fi
我提供的选项使其每秒重试一次,最多15秒钟。如果希望它永远等待,请删除“ -r”标志。
如果您仅在Unix上运行,请使用fifos。您可以将工作记录写入fifo,并让进程从该文件中读取数据,并且您的阅读器将阻塞fifos。
锁定文件还可以,但是对于您的描述,我会选择fifos
如此处发布:“ 使用Shell脚本正确锁定吗? ”,使用FLOM(Free LOck Manager)工具,序列化命令和Shell脚本变得像运行一样容易
flom -- command_to_serialize
FLOM允许您实现更复杂的用例(分布式锁定,读取器/写入器,数字资源等),如此处所述:http : //sourceforge.net/p/flom/wiki/FLOM%20by%20examples/
make(1)
接管的方式来表达依赖性吗?(即,make -j 9
如果您有8个核心,该怎么办)?这具有以更细粒度进行交织工作的附加优势。