fork () 및 신호가 프로세스에 전달되는 방법


13

C fork ()로 작성한 프로그램은 자식 프로세스에서 벗어납니다. 두 프로세스 모두 종료되지 않습니다. 명령 줄에서 프로그램을 시작하고 control-c를 누르면 어떤 프로세스가 인터럽트 신호를 수신합니까?

답변:


20

우리는 그것을 시도하고 보지 않겠습니까? 다음 은 부모 프로세스와 자식 프로세스를 모두 signal(3)트랩 SIGINT하고 프로세스가 도착했을 때이를 식별하는 메시지를 인쇄하는 데 사용하는 간단한 프로그램 입니다.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void parent_trap(int sig) {fprintf(stderr, "They got back together!\n");}
void child_trap(int sig) {fprintf(stderr, "Caught signal in CHILD.\n");}
int main(int argc, char **argv) {
    if (!fork()) {
        signal(SIGINT, &child_trap);
        sleep(1000);
        exit(0);
    }
    signal(SIGINT, &parent_trap);
    sleep(1000);
    return 0;
}

이라고 부릅시다 test.c. 이제 우리는 그것을 실행할 수 있습니다 :

$ gcc test.c
$ ./a.out
^CCaught signal in CHILD.
They got back together!

터미널에서 생성 된 인터럽트 신호는 활성 프로세스 그룹으로 전달되며 여기에는 parent 및 child가 모두 포함됩니다 . 둘 다 볼 수 child_trap와는 parent_trapI 누를 때 실행되었다 Ctrl- C.

POSIX에서와 신호 사이의 상호 작용에fork 대한 긴 토론이 있습니다. 여기에서 가장 중요한 부분은 다음과 같습니다.

fork () 이후에 프로세스 그룹으로 전송 된 신호는 부모와 자식 모두에게 전달되어야합니다.

또한 일부 시스템은 특히 신호가 시간에 매우 가깝게 도착할 때 정확하게 작동하지 않을 수 있습니다 fork(). 이러한 시스템 중 하나를 사용하고 있는지 확인하려면 각 개별 시도에서 상호 작용이 거의 없기 때문에 코드를 읽거나 운이 많이 필요할 것입니다.

다른 유용한 점은 다음과 같습니다.

  • 수동으로 생성되어 개별 프로세스로 전송 된 신호는 (아마도로 kill) 부모 또는 자식인지 여부에 관계없이 해당 프로세스 에만 전달 됩니다 .
  • 신호 처리기가 프로세스간에 실행되는 순서는 정의되어 있지 않으므로 먼저 실행하는 것에 의존 할 수 없습니다.
  • 당신이 경우 하지 않는 인터럽트 핸들러를 정의 (또는 명시 적으로 신호를 무시), 두 프로세스 단지와 함께 종료 할 SIGINT코드 (기본 동작).
  • 하나가 비 치명적으로 신호를 처리하고 다른 하나는 신호를 처리하지 않으면 처리기가없는 신호는 죽고 다른 신호는 계속됩니다.

나는 껍질이 흥미로운 방식으로 방해 할 수 있다고 생각합니까? 그들이 덫을 놓을 수 있다는 신호라면, 그것을 아이들에게 보낼 수 있습니까? (그런 다음 SIGHUP이 있습니다) (이 모든 것은 OS가 신호를 보내지 않지만 자식 프로세스는 부모에게 신호의 영향을받지 않을 수도 있음을 의미합니다 ...)
— Gert van den Berg
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.