나는 꽤 오랫동안 리눅스 커널 동작을 연구 해 왔으며 항상 나에게 분명하다.
프로세스가 죽으면 모든 자식은 프로세스가
init
끝날 때까지 프로세스 (PID 1)로 돌아갑니다 .
그러나 최근 커널보다 더 많은 경험을 가진 사람이 나에게 다음과 같이 말했습니다.
프로세스가 종료되면 모든 하위 항목도 종료됩니다 (
NOHUP
이 경우 다시 사용하지 않는 한init
).
지금, 나는 이것을 믿지 않지만, 그것을 확인하기 위해 여전히 간단한 프로그램을 작성했습니다. sleep
프로세스 스케줄링에 의존하기 때문에 테스트 에 시간 ( )에 의존해서는 안된다는 것을 알고 있지만,이 간단한 경우에는 충분하다고 생각합니다.
int main(void){
printf("Father process spawned (%d).\n", getpid());
sleep(5);
if(fork() == 0){
printf("Child process spawned (%d => %d).\n", getppid(), getpid());
sleep(15);
printf("Child process exiting (%d => %d).\n", getppid(), getpid());
exit(0);
}
sleep(5);
printf(stdout, "Father process exiting (%d).\n", getpid());
return EXIT_SUCCESS;
}
다음은 대화 ps
할 때마다 관련 결과 와 함께 프로그램의 출력입니다 printf
.
$ ./test &
Father process spawned (435).
$ ps -ef | grep test
myuser 435 392 tty1 ./test
Child process spawned (435 => 436).
$ ps -ef | grep test
myuser 435 392 tty1 ./test
myuser 436 435 tty1 ./test
Father process exiting (435).
$ ps -ef | grep test
myuser 436 1 tty1 ./test
Child process exiting (436).
보시다시피, 이것은 내가 예상했던 것처럼 작동합니다. 고아 프로세스 (436)는 init
죽을 때까지 (1)로 다시 주어진다 .
그러나이 동작이 기본적으로 적용되지 않는 UNIX 기반 시스템이 있습니까? 프로세스의 사망이 모든 아동의 사망을 즉시 유발할 수있는 시스템이 있습니까?
답변
프로세스가 종료되면 모든 자식도 죽습니다 (NOHUP을 사용하지 않으면 다시 초기화됩니다).
이것은 잘못이다. 죽었어 그 말을 잘못한 사람이나 일반적인 상황과 특정 상황을 혼동 한 사람.
프로세스 의 죽음이 간접적으로 자녀의 죽음을 초래할 수있는 두 가지 방법이 있습니다. 터미널을 닫을 때 발생하는 상황과 관련이 있습니다. 터미널이 사라지면 (사전에는 사용자가 터미널 에뮬레이터 창을 닫았 기 때문에 모뎀 행업으로 인해 직렬 회선이 끊어 졌기 때문에 SIGHUP 신호 가 해당 터미널에서 실행중인 제어 프로세스로 전송 됩니다. 일반적으로 초기 쉘이 시작됨) 그 터미널에서. 쉘은 일반적으로 종료하여 이에 반응합니다. 종료하기 전에 대화식으로 사용하기위한 쉘은 시작한 각 작업에 HUP를 보냅니다.
쉘에서 작업을 시작하면 작업 nohup
이 신호를 무시하므로 터미널이 사라질 때 죽으라는 지시를받지 않기 때문에 HUP 신호의 두 번째 소스 가 중단됩니다. 쉘에서 작업으로의 HUP 신호 전파를 차단하는 다른 방법에는 쉘 disown
내장 기능이있는 경우 내장 된 기능 사용 (작업이 쉘의 작업 목록에서 제거됨) 및 이중 분기 (쉘이 하위를 실행하는 하위를 시작 함)가 포함됩니다. 껍질은 손자에 대한 지식이 없다).
다시 말하지만, 터미널에서 시작된 작업은 부모 프로세스 (쉘)가 죽기 때문이 아니라 부모 프로세스가 작업을 종료하라는 명령을 받으면 작업을 종료하기로 결정하기 때문에 죽습니다. 그리고 터미널의 초기 쉘은 부모 프로세스가 죽기 때문이 아니라 터미널이 사라지기 때문에 죽습니다 (우연히 터미널이 쉘의 부모 프로세스 인 터미널 에뮬레이터에 의해 제공되기 때문일 수도 있고 아닐 수도 있습니다).
답변
프로세스가 종료되면 모든 자식도 죽습니다 (NOHUP을 사용하지 않으면 다시 초기화됩니다).
프로세스가 세션 리더 인 경우 올바른 것입니다. 세션 리더가 사망하면 SIGHUP이 해당 세션의 모든 구성원에게 전송됩니다. 실제로 그것은 그것의 아이들과 그들의 자손을 의미합니다.
프로세스는를 호출하여 세션 리더가됩니다 setsid
. 껍질은 이것을 사용합니다.
답변
따라서 위의 포스터는 아이들이 죽지 않고 부모가 그들을 죽이는 것입니다 (또는 그들에게 종료 신호를 보냅니다). 따라서 (1) 모든 자녀의 기록을 보관하고 (2) 모든 자녀에게 신호를 보내도록 부모를 프로그램하면 원하는 것을 가질 수 있습니다.
이것이 쉘이하는 일이며 부모 프로세스가하는 일입니다. 부모에게 HUP 신호를 포착해야 어린이를 죽일 수있는 충분한 통제력을 가질 수 있습니다.
답변
죽어가는 부모와 약간 관련이있는 답변에서 1 비트가 누락되었습니다. 프로세스가 더 이상 읽기 프로세스가없는 파이프에 쓸 때 SIGPIPE를 얻습니다. SIGPIPE의 표준 조치는 종료입니다.
이로 인해 프로세스가 실제로 종료 될 수 있습니다. 실제로 이것은 프로그램이 yes
죽는 표준 방법입니다 .
내가 실행하면
(yes;echo $? >&2)|head -10
내 시스템에서 답은
y
y
y
y
y
y
y
y
y
y
141
141은 실제로 128 + SIGPIPE입니다.
SIGPIPE 13 Term Broken pipe: write to pipe with no
readers
에서 man 7 signal
.