2種類のスクリプトがあります。
- jobA:複数のインスタンスを同時に実行できます。
- jobB:同時に1つのインスタンスしか実行できません。
jobB スクリプトは、jobA または jobB が実行されていない場合にのみ実行できます。
他のjobAはありますが、jobBは実行されていない場合はjobAスクリプトを実行できます。
私はこれのために一種のセマフォを使用しようとしました。利用可能なスロットをどこかに保存し、スロットが空になるまでロックする必要があるようです。
take 1
jobA
release 1
jobBは、すべてのスロットが空になるのを待ち、すべて占有しなければなりません。
take all
jobB
release all
GNU Parallelを試しましたが、実行時に実行されないようにsem
する方法が見つかりませんでした。jobA
jobB
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
これを試してみて、彼らがあなたの目標を達成していることを確認してください。