为什么父母和孩子的pid都显示出来

时间:2014-10-23 14:07:07

标签: c fork

我已经创建了这个程序循环5次,用fork()创建一个子进程,并将PID放入一个int数组,并在循环时输出每个数组元素,但为什么它显示父和子PID。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>

void main() {
    int i, nPIDStore[12];
    for (i = 0; i <5; i++) {
        fork();
        nPIDStore[i] = getpid();
        printf("%d\n", nPIDStore[i]);
        getchar();
    }
    exit(0);
}

感谢您的回复。

3 个答案:

答案 0 :(得分:2)

因为您在执行getpid()并打印它时没有区分父级和cild ..

您知道fork()向子进程返回0,向父进程返回子进程的pid,所以

flag = fork();
if(flag == 0)
{
    //this will be executed in the child process
    nPIDStore[i] = getpid();
    printf("%d\n", nPIDStore[i]);
}

但是,再次在循环中这样做。最后一次迭代的子节点也将成为下一次迭代的父节点..这将导致创建(2^5)-1子节点处理..所以记住这一点..

答案 1 :(得分:1)

这里有几个错误:

  1. 您的所有孩子也fork(),这意味着您将创建5 * 4 * 3 * 2 * 1 = 120个进程,这可能不是您想要的。当fork()返回0时,您就是孩子,所以除非您想要这种行为,否则您必须让孩子做其他事情。

  2. 您在nPIDStore中存储父级的PID,而不是子级的PID。您需要将fork()的结果存储在该数组中,如果您不存储该结果,则无法轻松获取您孩子的PID。

  3. 你没有wait()让你的孩子死去。在这种情况下,无论如何它们都会被init收获,但是自己等待它们会有更好的形式。

  4. 您不会检查任何系统调用的回复,包括fork()

  5. main()返回int

  6. 这可能更接近你想要的东西:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    int main(void)
    {
        int nPIDStore[12];
    
        for ( size_t i = 0; i < 5; ++i ) {
            pid_t p = fork();
            if ( p == -1 ) {
                perror("error calling fork()");
                return EXIT_FAILURE;
            }
            else if ( p == 0 ) {
    
                /*  In the child  */
    
                printf("Child %zu created with pid %d.\n", i + 1, (int) getpid());
                return EXIT_SUCCESS;    /*  Stop the child from doing anything else  */
            }
            else {
    
                /*  In the parent  */
    
                nPIDStore[i] = p;
                printf("Pid of child %zu is %d\n", i + 1, nPIDStore[i]);
            }
        }
    
        for ( size_t i = 0; i < 5; ++i ) {
            if ( waitpid(nPIDStore[i], NULL, 0) == -1 ) {
                perror("error calling waitpid()");
                return EXIT_FAILURE;
            }
            else {
                printf("Child %zu reaped.\n", i + 1);
            }
        }
    
        return 0;
    }
    

    和输出:

    paul@horus:~/src/sandbox$ ./fork
    Pid of child 1 is 9536
    Pid of child 2 is 9537
    Child 1 created with pid 9536.
    Pid of child 3 is 9538
    Child 2 created with pid 9537.
    Pid of child 4 is 9539
    Pid of child 5 is 9540
    Child 3 created with pid 9538.
    Child 1 reaped.
    Child 2 reaped.
    Child 3 reaped.
    Child 4 created with pid 9539.
    Child 5 created with pid 9540.
    Child 4 reaped.
    Child 5 reaped.
    paul@horus:~/src/sandbox$ 
    

答案 2 :(得分:0)

这就是fork的工作方式。 Fork创建过程映像的完整副本,包括过程介绍代码和当前指令指针。 fork返回后,您在fork调用后的语句中有两个几乎相同的进程。一个(子)从fork接收0作为返回值,另一个(父)接收到新创建的进程的进程ID。

也许您想要以下内容。

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

const size_t nr_children = 5;

int main() {
    pid_t children[nr_children];

    for (size_t i = 0; i < nr_children; ++i) {
        children[i] = fork();
        if (children[i] == 0) {
            printf("In Child %d\n", getpid());
            exit(0);
        }
        else {
            printf("In Parent %d\n", children[i]);
            getchar();
        }
    }

    for (size_t i = 0; i < nr_children; ++i)
        waitpid(children[i], NULL, 0);

    exit(0);
}