叉子没有等待

时间:2014-04-06 02:49:38

标签: c switch-statement fork wait

我不确定我是否正确地解决了这个问题,我试图通过......创建7个进程

void err_sys(const char* x)
{
   perror(x);
   exit(1);
}


for(i = 1; i < 7; i++){
  switch(parent = fork()){
      case -1:
         err_sys("fork error");
      case 0:       //child
         printf("I'm the child, number %d(%d)\n", i, getpid());
         break;
      default:      //parent
         printf("I'm the parent(%d)\n", getpid());
         break;
  }
    if(parent)
       break;        //loop break
}

当我用prog |运行它时猫&gt;文件我获得了#34的6个输出;我是父母&#34;,每个都有不同数量的孩子。然而,有6个孩子用独特的pids制作。其他父母的pids,除了第一个匹配孩子的pid。这只是由于分叉而导致的输出问题吗?

1 个答案:

答案 0 :(得分:3)

您的代码不正确 a priori ;它做它做的。问题是“它做了你想要它做的事情”,但这一点并不清楚,因为你没有明确说明你想要做什么。

获得6个流程的一个原因是你有一个循环:

for (i = 1; i < 7; i++)

这会计入1,2,3,4,5,6和停止。你需要使用两种习语中的一种:

for (i = 0; i < 7; i++)      // Idiomatic C
for (i = 1; i <= 7; i++)     // Less idiomatic C

假设err_sys()在被叫时没有返回(如果有的话,你需要break;之后),那么:

  1. 处理分叉。如果fork失败,则该进程将通过err_sys()退出。
  2. 如果该过程是孩子(因此将错误名称的变量parent设置为0),那么代码将打印&#34;我是孩子&#34;然后离开开关,再次循环遍历循环。
  3. 如果进程是父进程(因此将错误名称的变量parent设置为非零值),则会打印&#34;我是父进程&#34;然后离开开关和循环。
  4. 只有来自第一个fork的子进程才能重新执行循环。但是,除了最后一个孩子之外,每个孩子都会在循环的下一次迭代中将自己标识为父级。

    缓冲I / O

    请注意,缓冲的I / O会使事情变得复杂。如果程序的输出写入终端,默认情况下将获得行缓冲输出。每个换行都会将数据写入终端。但是,当输出进入管道时,它被完全缓冲;当缓冲区已满或者进程退出时(或由于其他原因关闭标准输出),数据才会写入终端。因此,当输出转到管道时,第一个子节点只有其操作的输出,但第二个子节点的缓冲区中的第一个子节点以及它写的内容都打印了数据但没有刷新。第三个孩子有3个过程的输出,依此类推。

    您可以在打印语句之后(或fflush(0)之后,fflush(stdout)之前)添加switchif,看看它有何不同。您也可以在不重定向到管道的情况下运行代码,看看它有什么不同。