程序在C中使用switch语句的分叉过程

时间:2014-04-12 21:43:11

标签: c switch-statement fork

我正在尝试从父进程中分叉2个进程,但有时我会收到错误(程序没有完成),我不知道为什么:

pid_t pidA, pidB;
pidA = fork();
switch (pidA) {
    case -1: 
        // error handling
        return -1;
    case 0:
        // first child code
        break;
    default: {
        // parent code 1
        pidB = fork();
        switch(pidB) {
            case -1:
                // error handling
                return -1;
            case 0:
                // second child code
                break;
            default:
                // parent code 2, I think it's the same like parent code 1. Am I right?
                waitpid(-1, NULL, 0);
                printf("parent\n");
                break;
         }
         // parent code 3, again same like parent code 1 and 2 ???
         // when I use printf("Parent\n"); here it prints Parent 2 times and I don't know why.
     }
 }

有人可以帮我解决这个问题,找到问题所在。 一些解释会很棒。 谢谢

2 个答案:

答案 0 :(得分:1)

考虑流程树:

    P
   / \
  P   C1
 / \
P  C2

第一叉:拆分成P和C1

第二叉:分为P和C2

C1返回并且不打印任何内容。

C2从切换中断,打印Parent(注意大写p)并返回。

P打印parentParent

这就解释了为什么它会两次打印Parent


至于未完成的程序,请检查waitpid()的返回值并尝试相应地调试它。

答案 1 :(得分:0)

你到底想要做什么? 当您第一次进行分叉时,您的第一个子进程基本上什么都不做。 父进程将恢复并再次返回pidB,然后将继续执行,直到执行waitpid()函数。

我假设您正在尝试等待新的子代码执行,然后在父级继续打印“父级”之前终止。

你正在等待-1的PID,这可能应该是pidB

如果你在开关区外放一个printf(),孩子将在出路时打印“父”,与产生它的父母一样。如果您希望孩子立即终止,您可能需要一个return语句而不是break。

按原样运行代码,在第二个printf语句之外使用switch语句,这是我的输出,使用pidB显示正在打印的进程:

parent
Parent: pid=25046
Parent: pid=0

结果显示,孩子也是打印的孩子之一。

如果在内部开关案例0中添加一个返回而不是中断,这就是你得到的:

parent
Parent: pid=25095

这是我的建议

// parent code 1
    pidB = fork();
    switch(pidB) {
        case -1:
            // error handling
            return -1;
        case 0:
             // second child code
             break;
        default:
            // parent code 2, I think it's the same like parent code 1. Am I right?
            waitpid(pidB, NULL, 0); // wait for the child process to finish by using the PID of the child as the argument to waitpid
            printf("parent\n");
            break;
     }
     // the child will execute anything here unless you return or otherwise prevent the child process from getting here.