while 루프에서 여러 하위 프로세스를 생성하는 상위 프로세스가 있는 프로그램을 작성하려고 합니다. 테스트를 위해 4개의 프로세스(1개의 상위 프로세스와 3개의 하위 프로세스)만 생성하는 것으로 시작했습니다. 그러나 (내가 아는 한) 해당 줄로 돌아가는 재귀 기능이 없더라도 자식은 자신이 만든 줄 위에서 코드를 실행하는 것처럼 보입니다.
이것이 내가 지금 가지고 있는 것입니다:
int main() {
time_t start;
time_t end;
int i = 0;
pid_t pid;
start = time(NULL);
printf("Αρχική τιμή δευτερολέπτων %d\n", start);
pid = fork();
printf("%d ", pid);
while (i < 2) {
if (pid > 0) {
fork();
wait();
i++;
}
}
printf("check ");
printf("%d", pid);
if (pid > 0) {
end = time(NULL);
printf("%d\n", end - start);
}
return 0;
}
내 결과는 다음과 같습니다
Αρχική τιμή δευτερολέπτων 1547394155
29338 check 29338 0
29338 check 29338 0
29338 check 29338 0
29338 check 29338 0
printf ("%d ", pid)
따라서 그 당시에는 2개의 프로세스만 실행되어야 하지만 4번 실행되는 것처럼 보입니다 .
답변1
이는 "와 관련이 있습니다.왜 fork()를 사용하는 프로그램이 때때로 출력을 여러 번 인쇄합니까?".
이렇게 하면 printf("%d ", pid)
문자열이 개행 문자로 끝나지 않고 를 호출하지 않기 때문에 출력 버퍼가 즉시 플러시되지 않습니다. 이는 플러시되지 않은 버퍼가 하위 프로세스에 의해 상속되고 버퍼가 최종적으로 호출 될 때를 의미합니다. fflush(stdout)
마지막으로 printf()
(개행 문자 출력) 또는 프로그램 실행이 끝날 때 플러시할 때 원래 상위 프로세스의 PID를 여러 번 출력합니다.
fflush(stdout)
해당 호출 바로 뒤에 삽입하면 printf()
(적절한 헤더를 포함하고 wait()
올바르게 호출하는 것도 포함) 다음과 같은 결과가 발생합니다.
Αρχική τιμή δευτερολέπτων 1547400480
79301 0 check 793010
check 793010
check 793010
check 793010
또한 루프에서 무한 반복되는 프로세스 ( 값이 0 while
인 첫 번째 하위 프로세스 )를 얻게 됩니다.pid
답변2
첫째, wait()
인수 없이 호출하는 것은 허용되지 않습니다. wait(NULL)
상태 EFAULT
를 저장하려고 하면 실패하거나 메모리가 낭비됩니다.
나는 코드를 실행하지 않고 코드에서 무슨 일이 일어나고 있는지 설명하려고 노력할 것입니다. (저도 포크 폭탄을 접한 적이 있습니다. 정말 감사합니다).
pid = fork(); printf("%d ", pid); while (i < 2) { if (pid > 0) { fork(); wait(); i++; } }
첫 번째 프로세스 이후에는 fork
2개의 프로세스가 있습니다. 하위 프로세스에서는 pid
동일하므로 하위 프로세스는 그 이후에만 실행되므로 0
무한 루프에서 계속 실행됩니다 .i++
pid > 0
그 시점부터 pid > 0
루프 내부의 두 번째 분기에 의해 생성된 상위 및 모든 하위에서 변수 pid
는 어디에서나 다시 업데이트되지 않으므로 값은 true입니다.
그래서 fork()
루프 내부에서 생성됩니다(1)처음으로 부모 밑을 달리는 아이,(2)부모에서 두 번째 실행의 자식(삼)루프의 첫 번째 실행에서 생성된 자식 중 두 번째 실행에는 또 다른 자식이 있습니다.
이는 3 + 1 = 4개의 프로세스를 만들고 모두 함수의 끝까지 실행되며 main()
모두 pid > 0
true이므로 전체 내용을 인쇄합니다( printf("%d ", ...
루프 전에 추가된 플러시되지 않은 데이터 포함). while
.
참고로, dprintf(1 or 2, ...)
디버깅이 필요할 때마다 항상 이것을 사용해야 합니다 printf()
. 이렇게 하면 잘못된 버퍼링(및 발생에 대한 잘못된 두려움) dprintf()
도 제거됩니다.기준.