2016-12-22 10 views
1

私たちは多くのジェンキンプロジェクトを並行して実行しています。我々はpythonを使用しており、私たちはpyenvで仮想環境を管理することを選択しました。残念ながら、pyenvはよく知られているrace conditionです。この問題を回避するために、プロセスレベルでロックを実装したいと考えています。私がしたいことは:マルチプロセスシステムでロックを実装する方法は?

lock some resource (a file?) 
do my pyenv stuff 
unlock the resource 

私のスクリプトはbashで書かれています。どうすればbashでリソースのロック/ロック解除を実装できますか?

答えて

1

通常のファイルの代わりにシンボリックリンクを使用することを検討します。シンボリックリンクの作成はアトミックな操作であるためです。そこで、我々はこれを行うことができます:

lockfile=/path/to/lock.file 
# lockfile is a symlink that points the string that holds the PID of the locking process 
ln -s $$ $lockfile 2>/dev/null 
if [[ $? == 0 ]]; then 
    # got the lock - ln -s will fail if symlink exists already 
else 
    otherprocess=$(readlink $lockfile) 
    if [[ $otherprocess != $$ ]]; then 
     ps -p $otherprocess 2>/dev/null 
     if [[ $? != 0 ]]; then 
      # stale lock; remove and lock again 
      # this can result in race conditions 
      # probably, we can make the lock procedure as a function that is shared by concurrent bash scripts and have a random sleep before we remove the stale lock and proceed 
     fi 
    fi 
fi 
+1

いいですが、アドホックすぎます。それを行う既存のコマンドがあるようです:flock – dangonfast

+0

@delavnog:私は実装のためにシンボリックリンクを使ってロックを見ました。しかし、私は群れが良いことに同意する。 – codeforester

2

だから、クロスプロセスロックを望むことflockと呼ばれるコマンドがあるUnixの世界ではあなたの友人。これはOSレベルでアトミックな操作として実装されており、この種の作業には非常に便利です。 more about it hereを読むことができます。ここでは、あなたがそれを使用する方法である。

# Wait for lock on (fd 222) for 10 seconds 
    (flock -w 10 222 || exit 1 

    { 
     # Do the operations you want to here 
    }) 222>/path/to/lockfile 

いくつかのトリックはここにあります。まず、通常は出力リダイレクトを使用する場合、bashはフロックを試す前にファイルを最初に開きます。しかし、ここでは、()があるので、最初のコマンドが群を取るサブシェルを最初に開始します。 flockは、ファイルハンドル222上のロックを取得しようとする。Flockはファイル記述子をロックする。ファイル記述子をロックした後、{}のコードが実行されます。それが実行された後、ファイル記述子222の内容がロックファイルに書き込まれ(すなわち何もない)、ファイルが閉じられ、ロックが解除される。これは、ファイルを閉じるとロックを解除するCのようなものです。もちろん、何が起こっているのかをhereについて説明している有名な@CharlesDuffy(帽子の先端@codeforester)よりも上手く説明することはできません。

+0

ニース。なぜ中括弧? – dangonfast

+0

特に理由はありません。私はちょうど実際の作業をしているコードからロックを行っているコードを分けるためにそこにいるのが好きです。 – 2ps

+0

@ 2ps:コード実行中に構文エラーが発生しました。 – codeforester

関連する問題