2015-01-26 3 views
4

방금 ​​포크에 대해 배웠고, 포크에 대한 호출에서 자식 프로세스가 실행되기 시작합니다 (그렇지 않으면 포크가 재귀가 될 수 있습니까?).메인이 두 번 호출되는 이유는 무엇입니까?

int main() { 
    printf("%d: Common code1\n", getpid()); 
    if (fork() != 0) { 
    printf("%d: Parent code\n", getpid()); 
    } else { 
    printf("%d: Child code\n", getpid()); 
    } 
    printf("%d: Common code\n", getpid()); 
} 

출력은 다음과 같습니다 : 4 라인이 인쇄 된 이유

27380: Common code1 
27380: Parent code 
27380: Common code 
27380: Common code1 
27383: Child code 
27383: Common code 

이해가 안 그러나이 코드 (ideone link)에서

? 자식 프로세스에서 인쇄되어 main이라는 포크가 부모로부터 인쇄되었지만 fork가 main을 호출하지 않는다면 이해할 수 있습니다.

+0

[출력이 두 번 인쇄되는 이유는 무엇입니까?] (http://stackoverflow.com/questions/3822755/why-the-output-is-printing-twice) – leppie

+3

두 개를 선택 했습니까? 하나의 작은 문자 만 다른 매우 긴 문자열 *? 우리를 너무 미워하니? –

+0

매우 길어? 방금 복사하고 붙여 넣은 다음 1을 추가하는 것이 가장 빠른 차별화 전쟁이었습니다 –

답변

8

좋은 질문입니다! 나는 처음에는 조금 혼란 스러웠다.

printf을 사용하면 출력이 버퍼링됩니다. 즉, printf에 의해 인쇄 된 내용은 개행에 도달 할 때까지 또는 콘솔에서 stdout이 재 지정 될 때까지 프로그램이 종료 될 때까지 실제로 콘솔로 플러시되지 않습니다.

이 경우. 부모 PID의 stdout 버퍼가 fork 중에 자식에 복사됩니다. 그런 다음, 부모와 자식 모두 종료 전에 버퍼에 기록합니다. 이로 인해 중복 된 데이터가 인쇄됩니다.

Here이 이 호출되기 전에 fflush(stdout);을 포함하는 이데one 링크입니다.

+0

stdout은 '콘솔 장치'가 아닙니다. tty를 stdout과 충돌시키지 마십시오. 다른 것들입니다. –

+0

나는 stdout 뒤에있는 마법을 설명하려고 시도하지 않았다. 나는 그 문제와 관련하여 관찰 된 효과를 설명하고 해결책을 제시하려고 시도했다. 설명 주셔서 감사합니다! – millinon

2

버퍼링. Printf는 (보통) stdout에 아무 것도 쓰지 않습니다. 일부 내부 데이터 구조 만 업데이트합니다. 이러한 데이터 구조는 자식에 복제되며 스트림을 플러시하면 데이터가 기록됩니다. 포크를하기 전에 flush(stdout)해야합니다.

3

문제는 버퍼링에서 비롯됩니다. stdout이 터미널과 연결되어 있지 않으면 줄 버퍼가 없습니다. 작성한 문자열은 버퍼 내부에 머물 수있을 정도로 짧으며 프로그램 종료 후에 만 ​​기록됩니다. 따라서 먼저 프로세스 27380이 버퍼를 덤프 한 다음 버퍼를 덤프하는 27383 프로세스를 확인합니다. 27380: Common code1 라인은 포크 전에 플러시되지 않았으므로 원래의 프로세스와 분기 된 프로세스의 버퍼에 있습니다. 이 문제를 해결하기 전에 바로 fflush()로 전화하십시오.

관련 문제