Lar*_*ang 45 scripting semaphore bash
我想并行运行多个 Bash shell 脚本。但是,我想避免竞争条件。我可以为此目的使用哪些 Unix 命令真正具有原子性,我该如何使用它们?
Ric*_*rri 35
如果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"
}
Run Code Online (Sandbox Code Playgroud)
Ale*_*x B 35
#!/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
Run Code Online (Sandbox Code Playgroud)
这确保了“(”和“)”之间的代码一次仅由一个进程运行,并且该进程确实等待锁定的时间过长。
War*_*ung 12
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
Run Code Online (Sandbox Code Playgroud)
我给出的选项使它每秒重试一次,最多 15 秒。如果您希望它永远等待,请删除“-r”标志。
小智 7
系统调用mkdir()
在 POSIX 文件系统上是原子的。因此,以mkdir
只涉及一次调用的方式使用该命令mkdir()
将达到您的目的。(IOW,不要使用mkdir -p
)。相应的解锁rmdir
当然是。
注意事项:mkdir()
在网络文件系统上可能不是原子的。
归档时间: |
|
查看次数: |
28152 次 |
最近记录: |