상황이 이상해요.
"B", "C", "D" 등과 같은 다른 실행 파일의 이름을 매개변수로 사용하는 C로 작성된 프로그램 "A"가 있습니다. "A"의 주요 작업은 "B", "C" 등을 분기하고 시작한 다음 충돌이 발생하는지 확인하는 것입니다. 이 경우 충돌이 발생한 프로세스를 다시 시작합니다.
또한 프로세스 "A"는 RTC 동기화를 위해 별도의 스레드를 실행합니다. "A"로 시작합니다 /bin/sh -c A B C D etc
.
저는 임베디드 환경에 있으며 Linux 4.4.57에서 파생된 사용자 정의 커널을 사용하고 있습니다.
이제 문제가 발생합니다. 때때로 내 프로세스 "A"가 좀비가 됩니다!
내 관찰 중 일부:
- "A"를 시작한 상위 프로세스가
/bin/sh -c
여전히 존재합니다. - 하위 프로세스 "B", "C" 등은 종료되지 않았습니다.
- "A"는 신호에 반응합니다.
- 상위 프로세스를 종료하면
/bin/sh -c
"A"의 상위 프로세스는 init(1)이 되지만 프로세스는 여전히 좀비 프로세스입니다. - 좀비 "A"를 죽이는 유일한 방법은
kill -9 «pid-of-A»
; - RTC 동기화 스레드가 아직 실행 중입니다! ;
이제 "A"가 신호에 응답하고 내부 스레드가 계속 실행 중이므로 이 좀비 프로세스가 나를 미치게 만듭니다.
이 행동을 어떻게 설명해야 할까요? 커널 빌드 구성과 관련이 있을까요?
편집하다: 코드를 자세히 살펴본 결과 "A"가 다음 명령을 사용하여 데몬으로 시작되는 것을 발견했습니다.
start-stop-daemon -b --start --quiet --pidfile /var/run/A.pid --background --exec /bin/sh -- -c "A B C D > /var/log/log 2>&1"
고쳐 쓰다: pthread_exit()를 호출하여 동일한 동작을 복제할 수 있었습니다. 문제는 원본 소스에서 phread_exit에 대한 참조를 찾을 수 없다는 것입니다. 메인 스레드가 다른 모든 스레드의 활성 상태를 유지하는 것을 중지하는 다른 방법이 있습니까?
답변1
좀비 프로세스는 완료되었지만 여전히 프로세스 테이블에 항목이 있는 프로세스입니다. 예를 들어 해당 하위 프로세스가 아직 살아 있기 때문입니다(참조:위키피디아).
그러니까 말씀하신 대로 B, C, D가 죽지 않고 A가 완성되면 B, C, D도 완성될 때까지 좀비가 됩니다.
이는 정상적인 동작입니다.
따라서 이것은 A의 버그처럼 보입니다. 자식을 모니터링해야 하기 때문에 자식이 살아있는 동안 죽어서는 안 됩니다. A의 버그를 수정하고 좀비로 변할까봐 걱정하지 마세요.
답변2
pthread_exit()
함수에서 사용하는 경우 main()
,이 게시물기본 스레드가 좀비 상태로 들어갈 수 있지만 다른 스레드는 계속 실행됨을 나타냅니다. 소환은 완전히 합법적 pthread_exit()
이기 때문에 main()
이것이 정상이고 이 특별한 언데드는 무해하다고 가정합니다. 이를 무시하거나 거기에서 사용하는 main()
대신 다른 스레드를 기다릴 수 있습니다 pthread_exit()
.
답변3
dmesg를 살펴보며 문제와 해결책을 찾았습니다. proc 파일의 사용자 정의 커널 함수로 인해 발생한 "내부 오류: 죄송합니다: 817 [#1] ARM"이 있음을 발견했습니다. 좀비가 된 프로세스의 메인 쓰레드가 proc 파일을 읽어오는데, 가끔 이 작업으로 인해 메인 쓰레드가 죽는 경우가 있는데... @muru 님의 답변과 정확히 같습니다. 기능을 수정했는데 이제 프로세스가 더 이상 종료되지 않습니다. 어쨌든, 모두 감사합니다.