スクリプトのための複雑なセマフォ

スクリプトのための複雑なセマフォ

2種類のスクリプトがあります。

  • jobA:複数のインスタンスを同時に実行できます。
  • jobB:同時に1つのインスタンスしか実行できません。

jobB スクリプトは、jobA または jobB が実行されていない場合にのみ実行できます。

他のjobAはありますが、jobBは実行されていない場合はjobAスクリプトを実行できます。


私はこれのために一種のセマフォを使用しようとしました。利用可能なスロットをどこかに保存し、スロットが空になるまでロックする必要があるようです。

take 1
jobA
release 1

jobBは、すべてのスロットが空になるのを待ち、すべて占有しなければなりません。

take all
jobB
release all

GNU Parallelを試しましたが、実行時に実行されないようにsemする方法が見つかりませんでした。jobAjobB

sem -j 3 'sleep 4;echo jobA 1 finished';   echo jobA 1 running
sem -j 3 'sleep 4;echo jobA 2 finished';   echo jobA 2 running
sem -j 3 'sleep 4;echo jobA 3 finished';   echo jobA 3 running
sem -j 3 'sleep 4;echo jobA 4 finished';   echo jobA 4 running
sem -j 1 'sleep 4;echo jobB a finished';   echo jobB 1 running
sem -j 1 'sleep 4;echo jobB b finished';   echo jobB 2 running
sem -j 3 'sleep 4;echo jobA 5 finished';   echo jobA 5 running
sem -j 3 'sleep 4;echo jobA 6 finished';   echo jobA 6 running
sem -j 3 'sleep 4;echo jobA 7 finished';   echo jobA 7 running
sem -j 3 'sleep 4;echo jobA 8 finished';   echo jobA 8 running
sem -j 1 'sleep 4;echo jobB c finished';   echo jobB 3 running
sem --wait; echo sem --wait done
jobA 1 running
jobA 2 running
jobA 3 running
jobA 1 finished
jobA 4 running
jobA 2 finished
jobA 3 finished
jobA 4 finished
jobB 1 running <--- this jobB waits for the jobAs above to complete
jobB 1 finished
jobB 2 running
jobA 5 running <---
jobA 6 running <--- these 2 started running but jobB 2 was still running
jobB 2 finished
jobA 5 finished
jobA 6 finished
jobA 7 running
jobA 8 running
jobA 7 finished
jobA 8 finished
jobB 3 running
jobB 3 finished

この動作を達成する方法はありますか?

答え1

私はソフトウェアパッケージflockのプログラムを使ってこれを行うことができると思いますutil-linux(つまり、ほとんどどこでも利用できるはずです)。

タスクAはロックされたファイルに対して読み取り(共有)ロックを取得し、タスクBは同じファイルに対して排他的ロックを取得します。これは次のことを意味します。

  • タスクBが排他的ロックを保持しない限り、タスクAは所望の数だけ並列に実行することができる。
  • ジョブ B は、他のジョブ A またはジョブ B がロックされたファイルに対して共有ロックまたは排他ロックを保持していない場合にのみ実行できます。

簡単な実装は次のとおりです。

存在するjobA.sh

#!/bin/sh

flock -s /tmp/job.lock bash <<'EOF'
echo "Start is job A"
sleep $((RANDOM % 20))
echo "End job A"
EOF

存在するjobB.sh

#!/bin/sh

flock -x /tmp/job.lock bash <<'EOF'
echo "Start is job B"
sleep $((RANDOM % 20))
echo "End job B"
EOF

これを試してみて、彼らがあなたの目標を達成していることを確認してください。

関連情報