为什么主进程创建了许多没有循环的子进程?

时间:2015-10-12 22:40:20

标签: c multithreading concurrency fork

我正在使用Eclipse Luna IDE在Debian发行版下使用C语言进行编程。

我的程序的主要过程应该只执行一次,因此只创建3个子进程,然后在所有子进程结束后结束。

我无法看到我的代码中出现了什么问题,但我的程序会创建3个以上不同父亲的孩子。

有人能告诉我如何获得预期的产出吗?

似乎主要功能正在执行多次,但它没有循环来执行它。

这是我的代码:

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

int main(){

    pid_t IMU1_PID, IMU2_PID, IMU3_PID;

    IMU1_PID=fork();
    IMU2_PID=fork();
    IMU3_PID=fork();

    if (IMU1_PID<0 || IMU2_PID<0 || IMU3_PID<0) { perror("fork"); exit(errno);}

    if(IMU1_PID==0){
        printf("child1's PID: %d - father's PID: %d\n",getpid(),getppid());
        sleep(2);
        exit(0);
    }
    if(IMU2_PID==0){
        printf("child2's PID: %d - father's PID: %d\n",getpid(),getppid());
        sleep(2);
        exit(0);
    }
    if(IMU3_PID==0){
        printf("child3's PID: %d - father's PID: %d\n",getpid(),getppid());
        sleep(2);
        exit(0);
    }

    printf("PARENT %d waiting until all CHILDS end\n",getpid());
    while(wait(NULL)!=-1);
    printf("PARENT %d after all CHILDS ended\n",getpid());

    return 0;
}

以下是输出:

PARENT 4282 waiting until all CHILDS end
child3's PID: 4285 - father's PID: 4282
child2's PID: 4284 - father's PID: 4282
child2's PID: 4286 - father's PID: 4284
child1's PID: 4288 - father's PID: 4283
child1's PID: 4283 - father's PID: 4282
child1's PID: 4287 - father's PID: 4283
child1's PID: 4289 - father's PID: 4287
PARENT 4282 after all CHILDS ended

这就像我期望的那样:

PARENT 4282 waiting until all CHILDS end
child3's PID: 4285 - father's PID: 4282
child2's PID: 4284 - father's PID: 4282
child1's PID: 4288 - father's PID: 4282
PARENT 4282 after all CHILDS ended

2 个答案:

答案 0 :(得分:1)

使用Erik Eidt的话“当你fork时,根据定义,fork()的函数的剩余部分(在这种情况下,main)在原始进程和新创建的流程。“

正如Charles所写,我之前的代码在调用fork()的第二次或第三次调用之前都没有检查pid!初始过程调用第一个fork(),然后父母和第一个孩子调用第二个fork(),然后原始过程和两个孩子中的每个将调用第三个fork()。< / p>

所以bellow是正确的代码:

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

int main(){

    pid_t IMU1_PID, IMU2_PID, IMU3_PID;

    IMU1_PID=fork();
    if (IMU1_PID<0) { perror("fork"); exit(errno);}
    if(IMU1_PID==0){
        printf("child1's PID: %d - father's PID: %d\n",getpid(),getppid());
        sleep(2);
        exit(0);
    }

    IMU2_PID=fork();
    if (IMU2_PID<0) { perror("fork"); exit(errno);}
    if(IMU2_PID==0){
        printf("child2's PID: %d - father's PID: %d\n",getpid(),getppid());
        sleep(2);
        exit(0);
    }

    IMU3_PID=fork();
    if (IMU3_PID<0) { perror("fork"); exit(errno);}
    if(IMU3_PID==0){
        printf("child3's PID: %d - father's PID: %d\n",getpid(),getppid());
        sleep(2);
        exit(0);
    }

    printf("PARENT %d waiting until all CHILDS end\n",getpid());
    while(wait(NULL)!=-1);
    printf("PARENT %d after all CHILDS ended\n",getpid());

    return 0;
}

答案 1 :(得分:0)

fork()的手册页中清楚地解释,函数1)如果失败则返回-1,2)如果成功,则返回父进程中的两个不同的进程(每个进程运行原始代码。)返回的值是子进程的pid。在子进程中,返回的值为0.发布的代码不检查返回的值,因此父进程和子进程正在执行对fork()的任何后续调用。

建议检查返回的值并使代码正确运行。

例如:

pid1 = fork();
if( pid1 <0 ) {handle error and exit}
if( pid1 ==0 ) { processing for child1 and exit}
// if got here then parent
pid2 = fork();
if( pid2 <0 ) { handle error and exit }
if( pid2 == 0) { processing for child2 and exit }
// if got here then parent
etc.