다음을 포함하는 bash 스크립트가 있습니다.while 루프프로세스를 종료하지 않고 백그라운드 프로세스가 while 루프를 중지하는 방법은 다음과 같습니다.멈추다배너
참고: 다음을 사용하면 내 스크립트가 작동합니다.죽이다하지만 함께정지 신호쓸모 없는
다음은 내 스크립트의 데모입니다(Kill 사용).
#!/bin/bash
background_processes=()
trap ctrl_c INT
ctrl_c() {
printf "\n[~] Killing background processes...\n"
for pid in "${background_processes[@]}"
do
kill $pid > /dev/null 2>&1
done
}
background_process() {
while true
do
sleep 5
printf "Hello World!\n"
done
}
start() {
for t in $(seq 1 10)
do
background_process &
background_processes+=(${!})
done
wait
}
printf "\n[I] Press 'ctrl+c' to kill background processes! \n"
start
이 방법은 효과적이지만 다른 방법은 그렇지 않습니다!
여기에 정지 신호가 있는 동일한 데모가 있습니다(아니요! )
#!/bin/bash
STOP=0
threads=10
finished_threads=0
trap ctrl_c INT
ctrl_c() {
printf "\n[~] Stopping background processes...\n"
STOP=1
# here i was checking that all the background processes is finish
while true
do
if [[ $finished_threads == $threads ]]
then
break
fi
done
printf "\n[+] Done\n"
}
background_process() {
while true
do
sleep 5
printf "Hello World!\n"
if [[ $STOP = 1 ]]
then
((finished_threads++))
break
fi
done
}
start() {
for t in $(seq 1 $threads)
do
background_process &
done
wait
}
printf "\n[I] Press 'ctrl+c' to stop background processes! \n"
start
왜 이것이 작동하지 않는지 말해 줄 수 있습니까?
추신: 그런데 저는 아랍어입니다. 영어 문법이 좋지 않다면 죄송합니다.
답변1
두 번째 예가 작동하지 않는 이유는 각 프로세스마다 고유한 주소 공간이 있으므로 $STOP
기본 프로세스에서 변수 값을 설정해도 백그라운드 프로세스에서 읽는 값에 영향을 미치지 않기 때문입니다.
백그라운드 작업자를 종료하는 간단한 방법은 첫 번째 예에서와 같이 신호를 사용하는 것입니다. 또 다른 접근 방식은 동기화를 위해 파이프를 사용하는 것입니다. 예를 들어 하위 프로세스가 비차단 읽기를 사용하고, 상위 프로세스가 종료하려고 할 때 파이프를 닫고, 하위 프로세스가 파이프가 닫혔음을 감지하면 종료됩니다.