我有一个小程序,需要按以下格式打印一些数字:
0 1 2 3 4
3
2
1
0
我尝试用这个C代码完成:
int main() {
int i;
for (i = 0; i < 5 && !fork(); i++) {
printf("%d ", i);
}
wait(NULL);
return 0;
}
但这打印
0 1 2 3 4
0 1 2 3
0 1 2
0 1
0
我无法弄清楚如何省略额外的数字。任何人都可以看到什么是错的吗?
答案 0 :(得分:1)
每次迭代fork
都是一个新孩子。父对象退出循环和wait
s,子进程打印迭代次数。但是,由于没有换行符,因此字符保持缓冲状态。但是,每个fork
都会以当前状态复制缓冲区。因此,每个孩子都会继承其祖先的所有印刷值,并在退出前等待其孩子死亡。因此,就像最后一个子项退出一样,缓冲区看起来像这样:
parent: ""
child-0 : "0 "
child-1 : "0 1 "
child-2 : "0 1 2 "
child-3 : "0 1 2 3 "
child-4 : "0 1 2 3 4 "
child-4退出(因为wait
不会阻塞),导致其stdout
缓冲区被刷新。这会导致child-3从wait
返回并退出,导致其stdout
缓冲区被刷新。这一直持续到父出口,所以你看到以下(所有在一行,因为在任何地方都没有新行):
0 1 2 3 4 0 1 2 3 0 1 2 0 1 0
要解决此问题,只需在打印前清空缓冲区即可。这会强制按顺序输出子缓冲区的子副本,然后当它们以相反的顺序退出时,子项的输出将出现:
int main() {
int i;
for (i = 0; i < 5 && !fork(); i++) {
fflush(stdout);
printf("%d ", i);
}
wait(NULL);
return 0;
}
给出:
0 1 2 3 4 3 2 1 0
答案 1 :(得分:0)