2017-04-07 26 views
0

我有这个小程序:我如何使'fork()'ed儿童分享标准输入?

#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读取,但预期它不工作。具体来说,它看起来像小孩“猪”的所有cat特德输入之一,因为该程序的功能大致是这样的:

2 
2 
2 

4 
0 
0 

我想我需要使用dup修复这个,但是在我们的课程资料中几乎没有任何内容,而且我在网上找到的所有内容都太复杂了,以至于我无法理解。我怎样才能使所有的流程分享stdin

+0

'dup()'不会帮助。你必须同步孩子,并阅读整个行...每一个更容易阅读stdin –

+0

这听起来像一个非常糟糕的主意,即使可能。谁会意识到输入是针对这个过程的?使用单个进程将输入发送给每个工作人员! – Olaf

+0

嗯..你的意思是'我怎样才能让两列火车共享相同的轨道'? – ThingyWotsit

回答

0

我该如何让'fork()'ed儿童分享stdin?

除非你做出规定,以避免它,份额stdin孩子。但是它们自己共享,这只是字节的通道。传输流的数据不是流的一部分。

具体来说,它看起来像小孩 “猪” 的所有catted输入之一,

是。这种具体的行为不能得到保证,但这似乎是合理的,而且事实上很可能。只有一个进程可以读取每个字节 - 从流中移除字节,以便其他进程不可用。围绕缓冲和分叉交互的一些细节细节可能会在某些情况下产生不同行为的外观,但避免这种并发症非常重要。

您需要不同的通信模式。以下是一些更合理的选择:

  • 预读。原始进程从流中读取所有需要的数据并将其记录在内存中。每个fork() ed孩子都继承了要使用的数据的副本。

  • 输入复用。主流程或其设置的附加流程负责读取stdin。它通过管道(每三个原始的孩子一个)将其所读取的任何内容转发给每个其他进程

  • 输入总线。子进程通过管道连接在一起(如果需要,可以在其标准流上进行设置);无论他们阅读的是什么数据,他们除了执行他们的日常工作之外,还会转到管道上的下一个孩子。

0

只有一个子进程从标准输入读取并清空文件输入缓冲区,它不会自动发送给所有子进程。 有关类似的情况,请参见Reading from stdin by multiple processes;请注意scanf也使用FILE *缓冲输入,所以结论是一样的。

它应该是读取并随后将输入数据逐个发送给所有孩子的父母。