2016-07-04 35 views
2

我想要做的是给每个孩子发送一条消息,然后看看哪一个先打印出来。我用一个管试图让我的代码如下所示:家长如何用一个管道向n个孩子发送消息?

int main() 
{ 
    int pfd[2]; 

    if(pipe(pfd)<0){ 
     perror("pfd error"); 
     exit(1); 
    } 

    int n=5; 

    for(int i=1;i<=n;i++){ 
     pid_t pid=fork(); 
     if(pid<0){ 
      perror("fork error\n"); 
      exit(1); 
     } 
     if(pid==0){ 
      close(pfd[1]); 
      char ms[256]; 
      int h; 
      read(pfd[0],&h,sizeof(int)); 
      read(pfd[0],ms,h*sizeof(char)); 
      cout<<i<<"_"<<ms<<endl; 
      close(pfd[0]); 
      exit(0); 
     } 
     if(pid>0){ 
      close(pfd[0]); 
     } 
    } 

    int j=1; 
    char uzenet[256]; 
    strcpy(uzenet,"start"); 
    int ho=strlen(uzenet); 
    while(j<=n){ 
     if(write(pfd[1],&ho,sizeof(int))==-1){ 
      perror("write error"); 
      exit(1); 
     } 
     if(write(pfd[1],uzenet,ho*sizeof(char))==-1){ 
      perror("write error"); 
      exit(1); 
     } 
     j++; 
    } 
    close(pfd[1]); 
    while(wait(NULL)>0){}; 
    exit(0); 
} 

而且它打印出这一点:

2_ 
1_start 
4_ 
3_ 
5_ 

但我想是这样的:

2_start 
1_start 
4_start 
3_start 
5_start 

回答

2

你可以只有一个管道!

从管道读取的数据被消耗,这意味着一旦从管道中读取某物将永远不可用,它将从管道中消失(考虑水和管道,饮用水会消耗水)。

如果您在不同进程之间共享管道的读取部分,那么它们将是并发的。这意味着你不能保证谁会读取一些数据。该系统能够在需要阅读的所有阅读器中选择他想要的任何阅读器。在最坏的情况下,一个进程会读取所有内容。一般来说,你会有一种随机选择。这不是随机的,但几乎不可能控制(当然也不是一个好主意)。至少不要考虑在写作部分重复N次的信息,并希望N个读者能够读取每一个副本。

管道不能用于广播某些东西。如果你需要它,实施你自己的广播系统。

---加入---

另外不要忘记,管道中的数据没有语义,没有消息的概念里面,如果你需要它,你就必须实现某种协议进行模拟。我的意思是说,你不能用公升和饮料滴,或者滔滔不绝的管道......

+0

呃,有趣的是,只有一个孩子的过程似乎消耗了“开始”部分。但当然你的答案是正确的。 –

+0

所以我应该为n个孩子创建n个管道,然后向他们发送“开始”? –

相关问题