자식 프로세스가 부모와 함께 죽는 UNIX 변형이 있습니까? sleep(15);

나는 꽤 오랫동안 리눅스 커널 동작을 연구 해 왔으며 항상 나에게 분명하다.

프로세스가 죽으면 모든 자식은 프로세스가 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.


답변