script.sh
에 의해run.sh
질소평행한. ~을 위한N=1, script.sh
프로세스는 실제로 시작되기 전에 30~45초 동안 절전 모드로 설정됩니다.
script.sh
모든 인스턴스를 주문하려면 어떻게 해야 합니까?N>1 시작하지 마세요처음까지 (N=1) script.sh
깨우다? 프로세스는 서로 직접 통신할 수 없습니다.
다른 프로세스에게 첫 번째 프로세스가 아직 대기 중이고 기다려야 하며 초기화되었지만 코드를 실행할 수 없다고 말하고 싶습니다.
프로세스는 서로 직접 통신할 수 없습니다.
답변1
N을 미리 알고 있다면 fifo를 세마포어로 사용할 수 있습니다.
mkfifo sem;
exec 3<>sem
rm -f sem
그런 다음 각 N>1 프로세스가 해당 프로세스에서 바이트를 읽도록 합니다 &3
. 이러한 바이트는 처음에는 사용할 수 없으므로 절전 모드로 전환됩니다.
N==1이 잠자기 상태를 마치면 N 바이트를 &3에 쓸 수 있으며 &3바이트를 기다리고 있던 모든 프로세스를 깨울 수 있습니다.
#!/bin/bash -e
mkfifo p
exec 3<>p
rm p
main()(
echo $FUNCNAME beg
sleep 2 &>/dev/null
printf '\n\n\n' >&3
echo $FUNCNAME end
)
worker()(
echo $FUNCNAME$1 beg
read -n 1 <&3
echo $FUNCNAME$1 end
)
main &
worker 1 &
worker 2 &
worker 3 &
wait
산출:
main beg
worker1 beg
worker2 beg
worker3 beg
main end
worker2 end
worker3 end
worker1 end
또 다른 접근 방식은 신호를 사용하는 것입니다. 스크립트가 터미널 작업 $$
(상위 쉘 pid)으로 실행되고 있는 것이 해당 프로세스 그룹의 프로세스 그룹 ID인지 확인할 수 있다면 작업자를 무기한 휴면 상태로 만들 수 있습니다(이상적으로는 함수 pause
를 호출하는 프로세스). sleep $hugevalue
전자는 하지 마세요) 그 전에 SIGUSR1과 같은 핸들러를 구축하도록 하세요. 기본 프로세스의 첫 번째 작업자는 이 신호를 무시해야 합니다. 그런 다음 첫 번째 작업자는 다른 모든 작업자에게 신호를 보내 작업자를 계속하게 할 수 있으며 kill -SIGUSR1 -$$
, 이로 인해 무기한 잠자는 사람이 죽게 됩니다.
#!/bin/bash
trap ' ' SIGUSR1
main()(
trap - SIGUSR1
echo $FUNCNAME beg
sleep 2 &>/dev/null
echo $FUNCNAME end
kill -s SIGUSR1 -$$
)
worker()(
trap ' ' SIGUSR1
echo $FUNCNAME$1 beg
sleep 10000000000 &>/dev/null
echo $FUNCNAME$1 end
)
main &
worker 1 &
worker 2 &
worker 3 &
wait
산출:
main beg
worker2 beg
worker1 beg
worker3 beg
main end
User defined signal 1
worker1 end
User defined signal 1
worker3 end
User defined signal 1
[1] 31554 user-defined signal 1 ./scr1
"user-defined signal 1"
( 메시지를 닫는 방법을 모르겠습니다 )
답변2
코드 조각을 보지 않고도 다음과 같이 보일 것이라고 추측할 수 있습니다.
for k in $(seq $N)
do
script.sh &
done
따라서 다른 작업을 실행하기 전에 첫 번째 작업이 완료될 때까지 기다리려면 다음을 수행할 수 있습니다.
for k in $(seq $N)
do
script.sh &
[[ $k == 1 ]] && wait
done
스크립트 자체를 실행하는 데 상당한 시간이 걸리면 작성한 요구 사항이 해결되지 않지만 수면과 처리를 분리할 수 없다면 원하는 것을 달성하는 것이 완전히 가능하다고 생각하지 않습니다. 귀하가 명시한 기준을 여전히 충족합니다.