Why am I forking more than 5 times here?

时光怂恿深爱的人放手 提交于 2019-12-10 15:27:16

问题


So I have code here, and I expected it to strictly run ls -l 5 times, but it seems to run far more times. What am I doing wrong here? I want to run ls 5 times, so I fork 5 times. Perhaps I don't understand the concept of wait properly? I went over a ton of tutorials, and none seem to tackle multiple processes using fork thoroughly.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main()
{
    pid_t pidChilds[5];

    int i =0;

    for(i = 0; i<5; i++)
    {
        pid_t cpid = fork();
        if(cpid<0)
            printf("\n FORKED FAILED");
        if(cpid==0)
            printf("FORK SUCCESSFUL");
        pidChilds[i]=cpid;
    }





}

回答1:


When you use fork in C, you have to imagine the process code and state being copied into a new process, at which point it begins execution from where it left off.

When you use exec in C, you have to imagine that the entire process is replaced if the call is successful.

Here is your code, re-written to produce the expected behavior. Please read the comments.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

int main()
{
    pid_t cpid;
    pid_t pidChildren[5];

    int i;
    for (i = 0; i < 5; i++)
    {
        cpid = fork();
        if (cpid < 0) {
            printf("fork failed\n");
        } else if (cpid == 0) {
            /*  If we arrive here, we are now in a copy of the
                state and code of the parent process. */
            printf("fork successful\n");
            break;
        } else {
            /*  We are still in the parent process. */
            pidChildren[i] = cpid;
        }
    }

    if (cpid == 0) {
        /*  We are in one of the children;
            we don't know which one. */
        char *cmd[] = {"ls", "-l", NULL};
        /*  If execvp is successful, this process will be
            replaced by ls. */
        if (execvp(cmd[0], cmd) < 0) {
            printf("execvp failed\n");
            return -1;
        }
    }

    /* We expect that only the parent arrives here. */
    int exitStatus = 0;
    for (i = 0; i < 5; i++) {
        waitpid(pidChildren[i], &exitStatus, 0);
        printf("Child %d exited with status %d\n", i, exitStatus);
    }

    return 0;
}



回答2:


You are forking in a loop and fork quasi-copies the process including the instruction-pointer.

Meaning: eg your first child-process will find itself in a loop that still has 4 rounds to go.

And each of the 4 processes that process spawns will find it has to go 3 rounds more.

And so on.

fork() returns whether the process you are in is the parent- or child-process. You should check that return value and break; the loop if you are in a child-process.

" On success, the PID of the child process is returned in the parent, and 0 is returned in the child. On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately. "

So you should if(cpid==0) break;.




回答3:


Every i'th fork starts off inside the loop, so it will run the remaining n-i iterations of that loop, forking recursively.



来源:https://stackoverflow.com/questions/15274016/why-am-i-forking-more-than-5-times-here

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