Output from fork() in c

我们两清 提交于 2019-12-23 01:02:07

问题


I recently ran into this piece of code, and don't fully understand it.

  1. What circumstances would cause pid == 0?
  2. 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:


  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 set errno to a value indicating why the fork(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.
  2. the wait(NULL); is not in the if (pid == 0), but in the else part, so it is indeed in the if (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 a wait(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 you exec(2) some other program in the child's process) You can learn if your child died because it exit(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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!