简体   繁体   English

叉子没有等待

[英]Forking WITHOUT waiting

I am unsure if I am correctly going about this, I am trying to create 7 processes total via... 我不确定我是否正确地解决了这个问题,我试图通过...创建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
}

When I run it with prog | 当我用prog |运行它时 cat > file I get 6 outputs of "I am the parent", followed with various amounts of children each. cat> file我得到了“我是父母”的6个输出,每个都有不同数量的孩子。 However, there are 6 children made with unique pids. 然而,有6个孩子用独特的pids制作。 The other parent pids, other than the first match a child pid. 其他父母的pids,除了第一个匹配孩子的pid。 Is this just some problem that comes with output due to forking? 这只是由于分叉而导致的输出问题吗?

Your code is not incorrect a priori ; 您的代码先验不正确; it does what it does. 它做它做的。 The issue is 'does it do what you want it to do', and that is not clear because you've not clearly stated what you are trying to do. 问题是“它做了你想做的事情”,这一点并不清楚,因为你没有明确说明你想要做什么。

One reason you get 6 processes is that you have a loop: 获得6个进程的一个原因是你有一个循环:

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

This counts 1, 2, 3, 4, 5, 6 and stops. 这计数1,2,3,4,5,6和停止。 You need to use one of two idioms: 你需要使用两种习语中的一种:

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

Assuming that err_sys() does not return when called (if it did, you'd need a break; after it), then: 假设err_sys()在被调用时没有返回(如果有的话,你需要break;在它之后),然后:

  1. The process forks. 过程分叉。 If the fork fails, the process exits via err_sys() . 如果fork失败,则进程通过err_sys()退出。
  2. If the process is the child (so the misnamed variable parent is set to 0), then the code prints "I'm the child" and then leaves the switch, and iterates around the loop again. 如果进程是子进程(所以错误命名的变量parent设置为0),则代码打印“我是孩子”,然后离开开关,并再次循环遍历循环。
  3. If the process is the parent (so the misnamed variable parent is set to a non-zero value), it prints "I'm the parent" and then leaves both the switch and the loop. 如果进程是父进程(所以将错误命名的变量parent设置为非零值),它将打印“我是父进程”,然后保留交换机和循环。

Only the child from the first fork gets to re-execute the loop. 只有来自第一个fork的子进程才能重新执行循环。 However, each child except the last gets to identify itself as the parent on the next iteration of the loop. 但是,除了最后一个孩子之外,每个孩子都会在循环的下一次迭代中将自己标识为父级。

Buffered I/O 缓冲I / O.

Note that buffered I/O complicates things. 请注意,缓冲的I / O使事情复杂化。 If the output of the program is written to the terminal, you will get line buffered output by default. 如果程序的输出写入终端,默认情况下将获得行缓冲输出。 Each newline causes the data to be written to the terminal. 每个换行都会将数据写入终端。 However, when the output goes to a pipe, it is fully buffered; 但是,当输出进入管道时,它被完全缓冲; the data only gets written to the terminal when the buffer is full, or the process is exiting (or closes standard output for some other reason). 当缓冲区已满或者进程退出时(或由于其他原因关闭标准输出),数据才会写入终端。 Thus, when the output goes to a pipe, the first child has the output from just its operations, but the second child has the data printed, but not flushed, by the first child in its buffer as well as what it wrote. 因此,当输出进入管道时,第一个子节点仅具有其操作的输出,但第二个子节点的缓冲区中的第一个子节点以及它所写的内容都打印了数据但未刷新。 The third child has 3 process's worth of output, and so on. 第三个孩子有3个进程的输出值,依此类推。

You could add fflush(0) or fflush(stdout) after the print statements (or just after the end of the switch , before the if ) and see what a difference it makes. 您可以在打印语句之后(或者在switch结束之后,在if之前fflush(0)添加fflush(0)fflush(stdout) ,并查看它有何不同。 You can also run the code without redirecting to a pipe and see what a difference that makes. 您也可以在不重定向到管道的情况下运行代码,看看它有什么不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM