使用嵌套开关分叉两个孩子

时间:2014-08-12 05:24:09

标签: c switch-statement exec fork

我正在尝试使用嵌套开关分叉两个子节点并执行它们()。但是,我的代码似乎没有为我的第二个孩子输入案例。

// fork the first child 
switch (player0PID = fork()){
    case -1: // error
        return -1;
    case 0: // in child
        // exec ("turn into") a new program
        // first child successfully execs
        execl("./client", "0", "&", (char *) NULL);
        _exit(127); // failed exec
    default: // inside parent 
        // fork second child
        switch (player1PID = fork()){
            case -1: // error
                printf("err spawning of client 1");
                return -1;
            case 0: // in child
                // exec ("turn into") a new program
                // below exec does not execute
                // second child not exec'd
                execl("./client", "1", "&", (char *) NULL);
                _exit(127); // failed exec
            default: // inside parent 
                ;
                // a lot of code the parent executes
                break;
        break; 

我的switch语句出错了吗?第一个孩子执行得很好,父代码就会执行。但是,我的第二个孩子由于某种原因没有被分叉或执行。代码不会进入第二个开关的“case 0”。


更新

解决方案是为了纠正我对execl的使用。

我的第二个exec失败了,因为两个exec语句将&作为程序的参数。为了正确处理&,我需要使用sh程序运行程序。第二个exec可能没有用,因为不允许在前台同时运行两个进程?

示例execl用法:

execl("/bin/sh", "sh", "-c", "./client 1 &", (char *) NULL);

2 个答案:

答案 0 :(得分:1)

fork()系统函数会将pid返回给父进程,将0返回给子进程。

在您的情况下,与第一个switch不同,第二个switch不执行父项和子项。

switch (player1PID = fork())

此条件仅执行父进程,这是您的第二个switch中的默认情况。而不是这种情况尝试以下条件 -

switch (fork() == 0)

在这种情况下,它将在第二个开关中执行case 0:(子)。但这次它不会执行default案例(父母)。

要避免此类错误,执行子进程和父进程的更好方法是使用nested if-else。尝试以下适用于您的代码 -

来自一个父流程的代码 - > 2个孩子的过程 -

int main()
{
    pid_t player0PID, player1PID;
    if(player0PID = fork()){
            // child 1
            printf("In child1 process\n");
            // do your stuff here
    }
    else{
            printf("In parent process\n");
            if(player1PID = fork()){
                    //child 2
                    printf("In child2 process\n");
                    // do your stuff
            }
            else{
                    printf("In parent process\n");                  
                    // do your stuff
            }
    }
    return 0;
}

来自父进程的代码 - > child1进程 - > child2进程 -

int main()
{
    pid_t player0PID, player1PID;
    if(player0PID = fork()){
            // child 1
            printf("In child1 process\n");
            // do your stuff here
            if(player1PID = fork()){
                    //child 2
                    printf("In child2 process\n");
                    // do your stuff
            }
            else{
                    printf("In child1 is parent process here\n");
                    // do your stuff
            }
    }
    else{
            printf("In parent process\n");
            // do your stuff here
    }
    return 0;
}

答案 1 :(得分:1)

printf()输出未出现的关键原因是您没有使用换行符终止它。这意味着它在子进程中保持缓冲,但这意味着当exec()发生时,缓冲的输出将丢失。您需要在格式字符串的末尾添加fflush(stdout);fflush(0);或换行符。这是一般指南 - 使用换行符结束printf()格式字符串,除非您希望在同一行输出上遵循其他内容。

就个人而言,我不喜欢处理货叉的开关;我使用if语句。但是,这些开关确实有效。