저는 초기화 스크립트와 메인 서비스가 데몬으로 실행되는 매우 복잡한 애플리케이션을 가지고 있습니다. 빠르고 우아하게 멈추고 싶어서 stop() 함수에 다음을 사용했습니다.
group_id=$(ps -o pgid= $(cat $pidfile))
if [ ! -z $group_id ]; then
kill -- -$group_id
success
fi
모든 하위 프로세스/스레드에 종료 신호를 보냅니다. 하지만 그 중 일부가 새로운 하위 프로세스를 생성한다면 어떻게 될까요? 이러한 새로운 하위 프로세스가 제대로 작동하지 않는 것 같지만 이것이 필요합니다. 상위 데몬에 종료 신호를 보내면 모든 하위 프로세스가 작업을 성공적으로 완료하지만 셸에서는 서비스가 중지된 것으로 표시됩니다(이전 항목을 확인하세요.모든 하위 프로세스가 중지된 경우에만 init 스크립트가 "OK"를 인쇄하도록 하려면 어떻게 해야 합니까?) 아마도 매우 분명한 것을 놓치고 있는 것 같지만 최소한의 노력으로 이 문제를 해결하는 방법을 여전히 모르겠습니다. 최소한 몇 가지 아이디어를 제공해주십시오.
답변1
프로세스 그룹 ID에 의한 종료는 원자성입니다. 단순히 잘못된 시간에 분기한다고 해서 프로세스가 탈출할 수는 없습니다. 이를 위해 kill
, fork
및 setpgid
를 순차적으로 수행되는 원자적 작업으로 생각할 수 있습니다 . 프로세스가 실행 중인 경우 하위 프로세스는 이후에 실행되면 if (!fork()) setpgid()
종료됩니다 .kill
fork
setpgid
이러한 새로운 하위 프로세스가 제대로 작동하지 않는 것 같습니다.
모든 하위 프로세스가 신호를 수신합니다. 이것이 프로세스 그룹의 모든 것입니다.
상위 데몬에 종료 신호를 보내면 모든 하위 프로세스가 작업을 성공적으로 완료하지만 셸에서는 서비스가 중지된 것으로 표시됩니다.
이것은 예상됩니다. 프로세스가 종료되기 전에 실제로 kill
스크립트로 돌아갑니다. 대상 프로세스가 현재 신호를 차단하고 있을 수 있습니다. 다중 프로세서 시스템에서는 종료된 프로세스가 kill -9
반환된 후 일부 작업을 수행하는 것을 볼 수 있습니다.
쉘 스크립트가 기본 프로세스가 종료되었는지 여부를 확인하면 기본 프로세스가 종료되었음을 나타냅니다. 프로세스 또는 프로세스 그룹 리더의 상위 프로세스 외에는 프로세스 또는 프로세스 그룹이 종료될 때까지 기다릴 수 있는 방법이 없습니다. 기본 프로세스를 시작할 때 아무 것도 설정하지 않으면 프로세스 그룹의 모든 프로세스가 종료되었는지 확인할 수 있는 편리한 방법이 없습니다.
그러한 상황을 처리하는 일반적인 방법은 다음과 같습니다.조절판종료 완료를 보고하고 종료하기 전에 완전히 종료되도록 하는 명령입니다(자식 프로세스에서 수행한 모든 작업 처리 포함). Apache HTTPD를 예로 들어 보겠습니다.
또는 미리 준비하면 프로세스 트리를 계측할 수도 있습니다. 바라보다마지막 백그라운드 애플리케이션의 PID를 얻는 방법