ファイルの共通ロックの競合状態?
質問
これは、ファイルシステムを使用してロックを作成する標準的な方法です。たとえば、visudoはそれを使用します。
[ -f ".lock" ] && exit 1
touch .lock
# do something
rm .lock
1)競合状態がありますが、Linuxはそれを使用しているため、混乱しています
2)シェルからファイルをロックするより良い方法はありますか?
3)または、代わりにディレクトリを使用する必要がありますか?
見つかった解決策:man lockfile。
解決
はい、サンプルスクリプトには実際に競合状態があります。テストとタッチの間に別のスクリプトが忍び込んだときに、レースの場合に失敗を取得するために、bashのnoclobberオプションを使用できます。
こちらに記載されています。重要な部分を抜粋し、いくつかの注釈を付けました(接頭辞BK:):
これに対する可能な解決策は、IOリダイレクトとbashのnoclobberモードを使用することです。これは既存のファイルにリダイレクトしません。次のようなものを使用できます。
if ( set -o noclobber; echo "$" > "$lockfile") 2> /dev/null;
then
# BK: this will cause the lock file to be deleted in case of other exit
trap 'rm -f "$lockfile"; exit $?' INT TERM EXIT
# critical-section BK: (the protected bit)
rm -f "$lockfile"
trap - INT TERM EXIT
else
echo "Failed to acquire lockfile: $lockfile."
echo "Held by $(cat $lockfile)"
fi
他のヒント
flockコマンドを試してください:
exec 200>"$LOCK_FILE"
flock -e -n 200 || exit 1
ロックファイルがロックされている場合は終了します。アトミックであり、NFSの最新バージョンで動作します。
テストを行いました。 0を含むカウンターファイルを作成し、2つのサーバーで同時に500回ループで次を実行しました。
#!/bin/bash
exec 200>/nfs/mount/testlock
flock -e 200
NO=`cat /nfs/mount/counter`
echo "$NO"
let NO=NO+1
echo "$NO" > /nfs/mount/counter
1つのノードが他のノードとロックのために戦っていました。両方の実行が終了したとき、ファイルの内容は1000でした。何度も試してみましたが、常に機能します!
注:NFSクライアントはRHEL 5.2で、使用されるサーバーはNetAppです。
簡単な解決策を見つけたようです:man lockfile
所属していません StackOverflow