问题
I recently ran into this piece of code, and don't fully understand it.
- What circumstances would cause pid == 0?
- Why does wait(NULL) cause the program to go into the if(pid == 0)
Basically I don't fully understand the output below. Any help would be appreciated. Thank you.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // standard POSIX header file
#include <sys/wait.h> // POSIX header file for 'wait' function
int main(void)
{
int i = -1;
int pid;
pid = getpid();
fprintf(stdout, "parent pid = %d\n", pid);
pid = fork();
if (pid == 0)
{
for (i = 0; i < 10; ++i)
{
fprintf(stdout, "child process: %d\n", i);
sleep(1);
}
exit(0);
}
else
{
fprintf(stdout, "child pid = %d\n", pid);
fprintf(stdout, "waiting for child\n");
wait(NULL);
fprintf(stdout, "child terminated\n");
}
fprintf(stdout, "parent terminating\n");
return 0;
}
Output:
parent pid = 2896
child pid = 5840
waiting for child
child process: 0
child process: 1
child process: 2
child process: 3
child process: 4
child process: 5
child process: 6
child process: 7
child process: 8
child process: 9
child terminated
parent terminating
回答1:
The
fork(2)
system call creates a second, child process and as a consequence, the call is called once in the parent, but returns in both, the parent and the child.Due to this, the code following the call needs some indication to know if we are executing code in the parent or the child, because this allows parent and child to divert from the common code from this point on.
The definition of
fork(2)
and it is stated in the manual page is:- to return
-1
and seterrno
to a value indicating why thefork(2)
call failed. - to return
0
for the child subprocess. - to return the
pid_t
child process id to the parent process (a positive number) so it can know the pid of the new subprocess just started.
- to return
the
wait(NULL);
is not in theif (pid == 0)
, but in theelse
part, so it is indeed in theif (pid != 0)
or in the parent process. The parent process must know if the child has finished and how, and must synchronise with it, for several reasons:the child can
exit(2)
before the parent, but depending on the child's amount of work, it can do after the parent finishes. In case the parent ends before the child, you'll get the shell prompt again, and your screen will be blurred with the output of the child, right after the prompt has been issued. This is not what you normally desire, so await(2)
call in the parent is just polite, so the shell only prompts you after everything has finished.A good test is to comment the
wait(2)
call in your example and see what happens.the
wait(2)
system call is a means of knowing how your child ended it's run (mostly if youexec(2)
some other program in the child's process) You can learn if your child died because itexit(2)
ed (and receive its exit code), because it was interrupted (and what the signal it received was) or if it has been stopped by the user/system for some reason.
A reading of fork(2)
, exec(2)
, exit(2)
and wait(2)
system calls (all as a group of related calls) will enlighten all the process relationships and how all these system calls collaborate to manage the unix process system.
回答2:
As mentioned in the comments by Susmit Agrawal and Jonathan Leffler, to briefly answer your first question:
The 0
is the returned value inside the child process after the fork() call succesfully returned. The execution of the child process starts in the if (pid == 0)
block. It iterates over the for
loop, prints
and sleeps
in each iteration, then in the end exit(0)
is called, and the child process terminates.
The execution of the parent process after the fork()
call continues in the else
block. The PID returned in the parent process is the PID of the child.
To answer your second question briefly:
wait(NULL) is used to wait for changes of state of the child process. In this specific case the state change is the termination of the child. The parameter NULL
simply means no status information will be stored.
For more detailed information please read the linked manual pages.
来源:https://stackoverflow.com/questions/54849218/output-from-fork-in-c