스크립트를 위한 복잡한 세마포어

스크립트를 위한 복잡한 세마포어

두 가지 유형의 스크립트가 있습니다.

  • jobA: 여러 인스턴스를 동시에 실행할 수 있습니다.
  • jobB: 동시에 하나의 인스턴스만 실행할 수 있습니다.

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

이것을 시도해보고 그들이 당신의 목표를 달성하는지 확인하십시오.

관련 정보