
我想並行運行多個 Bash shell 腳本。但是,我想避免競爭條件。 Unix 指令是什麼確實我可以用於此目的的原子,以及如何使用它們?
答案1
#!/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
這可確保「(」和「)」之間的程式碼一次僅由一個進程運行,並且該進程等待鎖定的時間不會太長。
答案2
如果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"
}
答案3
lockfile(1) 看起來是一個不錯的候選者,但要注意它是程式郵件軟體包,您可能尚未在電腦上安裝該軟體包。它是一個足夠流行的軟體包,如果尚未安裝,應該為您的系統打包它。我檢查的四個系統中有三個有它,另一個有它可用。
使用它很簡單:
#!/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”標誌。
答案4
也許 lockfile 命令可以滿足您的需求。
lockfile ~/.config/mylockfile.lock
.....
rm -f important.lock