포크 시스템 호출과 관련하여 매우 구체적인 질문이 있습니다. 나는 이 코드를 가지고 있습니다 :
int main (void)
{
for (int i = 0; i < 10; i++) {
pid_t pid = fork ();
if ( !pid ) {
printf("CHILD | PID: %d, PPID: %d\n", getpid(), getppid());
_exit(i + 1);
}
}
for (int i = 0; i < 10; i++) {
int status;
waitpid(-1, &status, 0);
if (WIFEXITED(status)) {
printf("IM %d AND CHILD WITH EXIT CODE %d TERMINATED\n",
getpid(), WEXITSTATUS(status));
}
else {
printf("ERROR: CHILD NOT EXITED\n");
}
}
return 0;
}
다음과 같은 출력이 생성됩니다.
CHILD | PID: 3565, PPID: 3564
CHILD | PID: 3566, PPID: 3564
IM 3564 AND CHILD WITH EXIT CODE 1 TERMINATED
IM 3564 AND CHILD WITH EXIT CODE 2 TERMINATED
CHILD | PID: 3573, PPID: 3564
CHILD | PID: 3567, PPID: 3564
IM 3564 AND CHILD WITH EXIT CODE 9 TERMINATED
IM 3564 AND CHILD WITH EXIT CODE 3 TERMINATED
CHILD | PID: 3568, PPID: 3564
IM 3564 AND CHILD WITH EXIT CODE 4 TERMINATED
CHILD | PID: 3569, PPID: 3564
IM 3564 AND CHILD WITH EXIT CODE 5 TERMINATED
CHILD | PID: 3570, PPID: 3564
IM 3564 AND CHILD WITH EXIT CODE 6 TERMINATED
CHILD | PID: 3571, PPID: 3564
IM 3564 AND CHILD WITH EXIT CODE 7 TERMINATED
CHILD | PID: 3572, PPID: 3564
IM 3564 AND CHILD WITH EXIT CODE 8 TERMINATED
CHILD | PID: 3574, PPID: 3564
IM 3564 AND CHILD WITH EXIT CODE 10 TERMINATED
이로 인해 포크가 정확히 어떻게 작동하고 새 프로세스가 실제로 어떤 코드를 실행하는지 궁금합니다. 위의 출력을 보면 이해할 수 없습니다.
- 어떻게두 번째 루프전에 인쇄첫째로모든 반복을 완료하시겠습니까? 나도 이거 눈치챘어두 번째는항상 상위 프로세스에 의해 실행되므로 실행 중인 동안 궁금합니다.먼저 for 루프,
if pid != 0
(상위 프로세스 호출을 나타냄)두 번째 루프처형(?) - CHILD 프로세스가 PID별로 정렬되어 인쇄되지 않는 이유는 무엇입니까?
그렇다면 가장 중요한 것은 포크가 정확히 어떻게 작동하며 누가 무엇을 수행하는가입니다.
답변1
을 실행하면 fork
커널은 분기된 프로세스의 복사본인 새 프로세스를 생성하고 두 프로세스 모두 이후에도 계속 실행됩니다. fork
반환 코드는 오류 발생 여부와 실행 중인 코드가 상위 프로세스인지 하위 프로세스인지 여부를 보여줍니다. 이 "계속 실행" 부분은 반드시 즉시 발생하지는 않습니다. 커널은 새 프로세스를 실행 대기열에 추가하기만 하면 결국 예약되고 실행되지만 반드시 즉시 발생하지는 않습니다.
이것은 귀하가 요구하는 두 가지 동작을 설명합니다.
- 새 프로세스가 즉시 예약될 필요는 없기 때문에 하위 프로세스가 실행되기 전에 상위 프로세스가 계속 실행될 수 있습니다.
- 생성 순서는 실행 대기열에 큰 영향을 미치지 않으므로 하위 프로세스가 생성된 순서대로 실행된다는 보장은 없습니다.