3

flockコードの2つの異なるインスタンスが複数回実行されるのを防ぐために、ファイルロックにbashコマンドを使用して遊んでいます。

私はこのテストコードを使用しています:

( ( flock -x 200 ;  sleep 10 ; echo "original finished" ; ) 200>./test.lock ) &
( sleep 2 ; ( flock -x -w 2 200 ; echo "a finished" ) 200>./test.lock ) &

2つのサブシェル(バックグラウンド)を実行しています。(flock NUM; ...) NUM>FILE構文はflockのマニュアルページからのものです。

最初のサブシェルがtest.lockで排他ロックを取得し、10秒待ってから、「元の終了」を出力し、常にロックを保持することを期待しています。2番目のサブシェルはほぼ同時に開始し、2秒待ってから、test.lockのロックを取得しようとしますが、2秒後にタイムアウトします。ロックを取得すると、「終了」と出力されます。ロックが取得されない場合、そのサブシェルは停止し、何も出力されないはずです。

最初のサブシェルはより長く待機しているため、10秒間ロックを保持します。したがって、2番目のサブシェルはロックを取得せず、終了しないはずです。つまり、両方ではなく、 「元の完成品」が印刷されているはずです。

実際には、「完成品」が印刷され、次に「元の完成品」が印刷されます。

これは、2番目のサブシェルが(a)最初のサブシェルと同じロックを使用していないか、(b)ロックの取得に失敗したが、実行を継続するか、(c)他の何かを使用していることを意味します。

なぜそれらのロックが期待どおりに機能しないのですか?

4

1 に答える 1

6

問題は、flockプロセスがタイムアウト内にロックを取得できなかった場合、親プロセス(つまり、プロセスを生成したシェル)を強制終了する方法がないことです。実行できるのは、失敗のリターンコードを返すことだけです。続行する前に、その戻りコードを確認する必要があります。

flock <params> && <do other stuff>

それで

( ( flock -x 200 ;  sleep 10 ; echo "original finished" ; ) 200>./test.lock ) & ( sleep 2 ; ( flock -x -w 2 200 && echo "a finished" ) 200>./test.lock ) &

あなたが望むことをします。

于 2010-05-24T11:43:44.730 に答える