fork () 후에 자식은 어디에서 실행을 시작합니까?


22

유닉스 프로그래밍을 배우려고하는데 fork ()에 관한 질문이 나왔습니다. fork ()가 현재 실행중인 프로세스와 동일한 프로세스를 생성한다는 것을 알고 있지만 어디에서 시작합니까? 예를 들어 코드가 있다면

int main (int argc, char **argv)
{
    int retval;
    printf ("This is most definitely the parent process\n");
    fflush (stdout);
    retval = fork ();
    printf ("Which process printed this?\n");

    return (EXIT_SUCCESS);
}

출력은 다음과 같습니다.

이것은 가장 확실하게 부모 프로세스입니다.
어느 프로세스가 이것을 인쇄 했습니까?
어떤 프로세스가 이것을 인쇄 했습니까?

나는 그것이 fork()동일한 프로세스 를 생성 한다고 생각 했기 때문에 처음에는 그 프로그램에서 fork()호출이 재귀 적으로 영원히 호출 될 것이라고 생각했습니다. 전화 fork()후 새로운 프로세스가 시작된 것 같아요 fork()?

부모 프로세스와 자식 프로세스를 구별하기 위해 다음 코드를 추가하면

if (child_pid = fork ()) printf ("This is the parent, child pid is %d\n", child_pid);
else printf ("This is the child, pid is %d\n",getpid ());

fork () 호출 후 자식 프로세스는 어디에서 실행을 시작합니까?


5
man fork질문에 대답하기에 충분할 것입니다. btw
alex

답변:


23

새로운 프로세스는 fork()호출 내에서 생성 되며 부모와 마찬가지로 프로세스 에서 반환됩니다. (당신이에 저장된 반환 값 retval에서)이 fork()될 것입니다 :

  • 자식 프로세스에서 0
  • 부모 프로세스에서 자식의 PID
  • 장애가 발생한 경우 상위 -1

테스트 코드가 올바르게 작동합니다. 그 반환 값을 저장 fork()에서 child_pid와 용도 if(이것은 에러를 확인하지 않더라도)는 '0'인지 아닌지 확인할


13

나는 fork ()가 동일한 프로세스를 생성한다고 생각했기 때문에 처음에는 해당 프로그램에서 fork () 호출이 재귀 적으로 영원히 호출 될 것이라고 생각했습니다. fork ()에서 생성 된 새로운 프로세스가 fork () 호출 후에 시작되는 것 같아요?

예. 줄 번호를 봅시다 :

int main (int argc, char **argv)
{
    int retval;                                               /* 1 */
    printf ("This is most definitely the parent process\n");  /* 2 */
    fflush (stdout);                                          /* 3 */
    retval = fork ();                                         /* 4 */
    printf ("Which process printed this?\n");                 /* 5 */
    return (EXIT_SUCCESS);                                    /* 6 */
}

실행 흐름은 다음과 같습니다.

caller process     fork()  ...
                          
original program            exec()  2  3  4  5  6
                                               
forked program                                   5  6

...받은 결과를 정확하게 설명합니다.

원래의 프로그램과 포크 된 프로그램이 어떻게 다른 방식으로 작동하는지 알고 싶다면, 반드시 동일한 코드를 공유하기 때문에 Michael Mrozek의 답변을 참조하십시오 .


1은 실제로 명령이 아닙니다. 또한 원본 프로그램과 분기 프로그램은 실제로 동시에 실행되지 않습니다. 둘 중 하나는 다른 프로그램이 양보 / 선점 될 때까지 기다려야합니다.
badp

1
멀티 코어 / 멀티 CPU 시스템에서 두 프로그램은 실제로 동시에 실행될 수 있습니다.
jlliagre

@jilliagre 멀티 코어 시스템은 실제로 멀티 스레딩에 관한 것입니다. CPU가 여러 개인 시스템의 경우 실제로 해당되는지 아닌지는 모르겠습니다 . 나는이 분야의 전문가가 아니며, 그럴듯한 시나리오처럼 보입니다. 우리가 OS가 동시에 여러 프로세스를 실행할 수 있다는 데 동의한다면 (그러면 동시성을 어떻게 처리 할 것인가?), 원래 프로그램이 CPU에서 명령 4를 실행할 때까지 다른 CPU는 다른 프로세스를 실행하는 데 바쁠 것입니다.
badp

특히 5 단계에서 약간의 I / O가 발생하는 기본 시스템 호출이있을 경우에는 매우 가능성이 높은 시나리오라고 말할 수 있습니다. CPU가 현재 시스템의 병목 현상이 거의 없기 때문에 모든 CPU를 사용중인 것은 실제로 일반적인 상황이 아닙니다. 멀티 스레딩과 멀티 코어를 혼란스럽게하는 것 같습니다.
jlliagre

8
난 그냥 그 대각선 화살표는 말을 언급 할 수 환상적인 .
JBirch

0

이것에 대한 진정한 해결책은

switch (fork()) {
    case -1 :
        fprintf (stderr, "fork failed (%s)\n", strerror(errno));
        break;
    case 0 :  // child process comes here
        break;
    default : // parent process
        break;
}

// all continue here

-1

의 바로 뒤에있는 코드 fork()가 하위 프로세스에 복사되고 상위 프로세스와 하위 프로세스를 혼합하지 않고 동일한 (중복, 공유되지 않은) 환경을 가진 두 개의 다른 엔티티입니다.

이제 출력을 참조하십시오 ...

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.