脚本的复杂信号量

脚本的复杂信号量

我有两种类型的脚本:

  • jobA:多个实例可以同时运行
  • jobB:同一时间只能运行一个实例

jobB 脚本只能在没有 jobA 或 jobB 运行时运行

如果有其他 jobA 但没有 jobB 运行,则 jobA 脚本可以运行


我想到为此使用某种信号量。我想我必须将可用的插槽保存在某处,并锁定直到一个插槽空闲,就像这样

take 1
jobA
release 1

jobB 必须等到所有插槽都空闲,然后将它们全部占用

take all
jobB
release all

我尝试使用semGNU 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

尝试一下这些,看看它们是否能实现你的目标。

相关内容