![/etc/rc.local에서 시작된 프로세스가 완료되면 kill()이 하위 프로세스를 중지하지 않습니까?](https://linux55.com/image/163731/%2Fetc%2Frc.local%EC%97%90%EC%84%9C%20%EC%8B%9C%EC%9E%91%EB%90%9C%20%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EA%B0%80%20%EC%99%84%EB%A3%8C%EB%90%98%EB%A9%B4%20kill()%EC%9D%B4%20%ED%95%98%EC%9C%84%20%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EB%A5%BC%20%EC%A4%91%EC%A7%80%ED%95%98%EC%A7%80%20%EC%95%8A%EC%8A%B5%EB%8B%88%EA%B9%8C%3F.png)
Raspberry Pi(최신 Raspberry Pi)에서 저는 네트워크 요청의 요구 사항에 따라 애플리케이션을 생성하고 다양한 네트워크 요청의 요구 사항에 따라 이를 종료하는 애플리케이션을 작성했습니다. 생성 메커니즘은 포크/실행입니다. 종료는 kill(childPid, SIGQUIT)을 통해 수행됩니다. 상상할 수 있듯이 이는 간단한 C++ 코드이며 잘 작동합니다.
즉, /etc/rc.local에서 시작하지 않으면 잘 작동합니다. 거기에서 실행하는 명령은 적절한 CD만 있으면 됩니다.
./effectPlayer &
잘 시작되고, 요청도 잘 받고, 빌드도 잘되지만(aplay에 걸쳐 있으므로 작동 시기를 알려주는 것이 간단함) 요청 시 aplay 하위 프로세스를 완전히 종료하지 못합니다. 평소와 같이 kill()을 호출하고, kill()은 0을 반환합니다. 하지만 플레이는 계속됩니다.
/etc/rc.local에서 생성하면 포크 또는 킬에서 특별한 동작이 제공되기 때문에 이것이 이상한 사실이라고 생각하지만 무엇을 이해하지 못합니다. 내가 무엇을 놓치고 있나요?
편집: 질문에 대한 답변을 추가했습니다. 로깅이 켜진 상태에서 /etc/rc.local에서 실행하면 애플리케이션이 다음을 보고합니다.
23:10:06 10-11-2019 (effectPlayer) 7: P1 64 elvenHall #command to start playing
23:10:06 10-11-2019 (sound) launched 1083: /usr/bin/aplay -q -... #what it forks/execs
23:10:10 10-11-2019 (effectPlayer) 7: X1000 #command to stop playing
23:10:10 10-11-2019 (sound) sending 3 to 1083, result 0 0 #what kill() is asked to do
번역 후에는 특정 효과를 재생하고 이를 처리하기 위한 플레이를 생성하도록 요청됩니다. 작동하고(오디오가 들림) 모든 재생을 중지하라는 명령을 보냅니다. 올바른 신호를 사용하여 올바른 PID에서 kill()을 성공적으로 호출하고, kill()은 errno=0으로 0을 반환합니다. aplay를 제외하고는 아직 실행 중입니다.
명령줄에서 동일한 시퀀스를 실행하면 aplay가 실제로 종료된다는 점을 제외하면 모든 것이 동일하게 작동합니다.
SIGQUIT를 SIGKILL로 바꾸면 예상대로 작동합니다. effectPlayer가 어떻게 시작되든 aplay가 종료됩니다.
지금은 게임의 이상한 점에 대해 설명하겠습니다. 나는 SIGKILL을 사용하는 것을 좋아하지 않습니다. 중요한 정리를 건너뛸 수 있습니다. 하지만 작동합니다 ...
답변1
포크와 exec가 이를 무시하기 때문에 부팅 스크립트에서 SIGQUIT 무시를 상속받았을 것입니다. 상위 프로그램에서 SIGQUIT를 기본 상태로 재설정하여 시도해 보세요.
답변2
이는 rc.local에서 실행되기 때문에 발생할 가능성이 없습니다.
먼저, 상위 프로세스가 실제로 신호를 보내고 있는지(여기서 일부 디버깅 라인이 필요할 수 있음) 하위 프로세스가 종료되지 않았는지 확인하십시오(pgrep aplay를 실행하고 상위 프로세스를 종료시킨 후 다시 pgrep aplay를 실행하십시오). 또한 SELINUX나 기타 MAC 이상한 현상이 발생하지 않는다고 가정합니다.
kill()에 응답하지 않는 프로세스는 권한, 처리, PID 등 몇 가지 요인으로 인해 발생할 수 있습니다. 하위 프로세스 "aplay"를 생성하는 상위 프로세스 "효과플레이어"가 있고 effectPlayer가 하위 프로세스에 종료 신호를 보내는 것 같습니다.
setuid 및 친구에게 이상한 작업을 하지 않는다고 가정하면 부모와 자식 모두 동일한 소유자를 갖게 되므로 괜찮습니다.
종료 신호를 차단할 수 있지만 aplay는 그렇게 하지 않을 것이라고 확신합니다. 그래서 가능합니다. SIGQUIT를 SIGKILL로 변경하고 변경되는지 확인할 수 있습니다.
마지막으로 PID가 있습니다. pid가 정확합니까? 다시 말하지만, 종료하려는 PID를 지적하고 이를 ps 명령과 일치시키는 일부 디버그 라인이 이를 테스트합니다. 때로는 셸에서 exec를 사용하여 잘못된 프로세스를 종료할 수도 있습니다.