fork () 분기가 예상보다 많습니까?


답변:


245

fork()프리미티브는 종종 상상력을 뻗어. 그것을 느낄 때까지 각 작업이 무엇인지 종이에 기록하고 프로세스 수를 설명해야합니다. fork ()는 현재 프로세스의 거의 완벽한 사본을 생성한다는 것을 잊지 마십시오. (가장 큰 목적으로) 가장 큰 차이점은 fork()의 반환 값이 부모와 자식간에 다르다는 것입니다. 이 코드는 반환 값을 무시하므로 차이가 없습니다.

처음에는 하나의 프로세스가 있습니다. 점과 루프를 인쇄하는 두 번째 프로세스를 만듭니다. 두 번째 반복에서 각각 다른 사본을 작성하므로 점을 인쇄 한 다음 종료하는 네 개의 프로세스가 있습니다. 따라서 예상대로 6 개의 점을 쉽게 설명 할 수 있습니다.

그러나 printf()실제로하는 것은 출력을 버퍼링하는 것입니다. 따라서 두 개의 프로세스 만 있었을 때의 첫 번째 점은 쓰여질 때 나타나지 않습니다. 이러한 점은 버퍼에 남아 있으며 fork ()에서 복제됩니다. 버퍼링 된 점이 나타나는 프로세스가 종료 될 때까지는 아닙니다. 버퍼링 된 도트를 인쇄하는 네 가지 프로세스와 새로운 도트는 8 개의 도트를 제공합니다.

이 동작을 피하려면 fflush(stdout);after로 전화하십시오 printf().


12
고맙게도 버퍼가 fork ()와 중복된다는 것을 몰랐습니다. 그런 이상한 행동을 설명합니다.
Nikolay Kovalenko 2016 년

1
8 개가 아닌 10 개의 점을 제공해서는 안됩니까? 4 세대 어린이는 버퍼링 된 점을 상속하고 자체 점을 추가 한 다음 종료시 비우기 때문에 총 8 개의 점을 인쇄하지만 두 번째 1 세대 프로세스는 여전히 각 버퍼링 된 1 개의 점을 가지며 출구에서 비 웁니다. (10) 총 부여
psusi

12
2 세대 프로세스 @psusi 하나 제 세대 방법. fork()2를 생성 한 다음 종료하지 않고 1 개의 프로세스 만 더 생성합니다.
이즈 카타

70

당신은이 출력 스트림에 커밋되지 않은 버퍼를 . stdout은 라인 버퍼링되며 버퍼는 나머지 프로세스와 함께 복제됩니다. 프로그램이 종료되면 커밋되지 않은 버퍼가 두 번 작성됩니다 (각 프로세스마다 한 번씩). 모두 사용

printf("a\n");

printf("a "); fflush(stdout);

문제를 나타내지 마십시오.

첫 번째 예에서는 출력 스트림 버퍼에 각각 두 개의 점이있는 네 개의 프로세스를 만듭니다. 각 스트림이 종료되면 버퍼를 플러시하여 8 개의 점을 생성합니다.


2

i = 0 일 때

Process_1 : 버퍼링 된 텍스트 = 1 점

Process_2 (Process_1에 의해 작성 됨) : 버퍼링 된 텍스트 = 1 점

i = 1 일 때

Process_3 (Process_1에 의해 작성 됨) : Process_1에서 1 개의 버퍼 된 점을 상속하고 자체적으로 1 개의 점을 인쇄합니다. 총 Process_3에서 2 개의 점을 인쇄합니다.

Process_4 (Process_2에 의해 작성 됨) : Process_2에서 1 개의 버퍼 된 점을 상속하고 자체적으로 1 개의 점을 인쇄합니다. 총 Process_4에서는 2 개의 점을 인쇄합니다.

Process_1 : 2 개의 점을 인쇄합니다 (i = 0이면 버퍼 된 점 하나, i = 1이면 다른 점)

Process_2 : 2 개의 점을 인쇄합니다 (i = 0이면 버퍼 된 점 하나, i = 1이면 다른 점)

최종 출력 : 8 도트. :)

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