我有这个小程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
int orig = 1;
for (int i = 0; (i != 3) && orig; ++i) {
orig = orig && fork();
}
if (orig) {
for (int i = 0; i != 3; ++i) {
wait(NULL);
}
} else {
int num;
scanf("%d", &num);
printf("%d\n", num*num);
}
}
它应该简单地对从stdin
读取的三个数字进行平方,但它不能按预期工作。具体来说,它看起来像一个孩子&#34; hogs&#34;所有cat
输入,因为程序大致如此:
2
2
2
到
4
0
0
我想我需要使用dup
来解决这个问题,但在我们的课程资料中几乎没有任何内容,我在网上找到的所有东西都太复杂了,我无法理解。我如何才能让所有流程共享stdin
?
答案 0 :(得分:0)
只有一个子进程从stdin读取并清空文件输入缓冲区,它不会自动发送给所有子进程。 有关类似情况,请参阅Reading from stdin by multiple processes;请注意,scanf也使用FILE *缓冲输入,所以结论是一样的。
应该是父母一个接一个地读取然后将输入数据发送给所有孩子。
答案 1 :(得分:0)
如何让fork()&#39; ed孩子共享stdin?
除非你做出规定以避免它,否则孩子做分享stdin
。但是他们共享流本身,这只是字节的管道。传输流的数据不是流的一部分。
具体来说,它看起来像一个孩子&#34; hogs&#34;所有被忽略的输入,
是。这种具体行为并不能得到保证,但这似乎是合情合理的。只有一个进程可以读取每个字节 - 从流中删除字节,以便其他进程不可用。缓冲和分叉的相互作用有一些细节,在某些情况下可能会产生不同的行为,但避免这些并发症很重要。
您需要不同的沟通模式。以下是一些更合理的选择:
预读。原始进程从流中读取所有需要的数据并将其记录在内存中。每个fork()
ed子项都会继承要使用的数据副本。
输入多路复用。它设置的主要过程或其他过程负责读取标准输入。它通过管道将其读取的内容转发给每个其他进程(三个原始孩子各一个)
输入总线。子进程通过管道连接在一起(如果需要,可以在其标准流上设置);无论他们阅读什么数据,除了执行他们的正常工作外,他们还会向管道上的下一个孩子转发。