我有两种类型的脚本:
- jobA:多个实例可以同时运行
- jobB:同一时间只能运行一个实例
jobB 脚本只能在没有 jobA 或 jobB 运行时运行
如果有其他 jobA 但没有 jobB 运行,则 jobA 脚本可以运行
我想到为此使用某种信号量。我想我必须将可用的插槽保存在某处,并锁定直到一个插槽空闲,就像这样
take 1
jobA
release 1
jobB 必须等到所有插槽都空闲,然后将它们全部占用
take all
jobB
release all
我尝试使用sem
GNU Parallel,但我找不到一种方法来确保在运行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 都可以并行运行
- 仅当没有其他作业 A 或作业 B 在锁定文件上持有共享锁或排他锁时,作业 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
尝试一下这些,看看它们是否能实现你的目标。