【问题标题】:How can a parent send a message to n children with one pipe?父母如何用一个管道向 n 个孩子发送消息?
【发布时间】:2016-07-04 16:51:00
【问题描述】:

我要做的是向每个孩子发送一条消息,然后看看哪个孩子先打印出来。我尝试过使用一个管道,所以我的代码如下所示:

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

【问题讨论】:

    标签: c++ linux pipe fork


    【解决方案1】:

    你不能只用一根管子!

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

    如果您在不同进程之间共享管道的读取部分,那么它们将是并发的。这意味着您无法保证谁将读取某些数据。系统能够在某个时间点请求阅读的所有阅读器中选择他想要的任何阅读器。在最坏的情况下,一个进程会读取所有内容。一般来说,你会有一种随机选择。它不是随机的,但几乎不可能控制(尝试肯定是个坏主意)。至少不要想着在写作部分复制N次消息,希望N个读者每人能读到一份。

    管道不能用于广播某些内容。如果需要,请实现您自己的广播系统。

    ---添加---

    另外不要忘记管道数据没有语义,内部没有消息的概念,如果你需要它,你必须实现一些协议来模拟它。我的意思是你不能用升水和饮料滴水淹没管道,或者相反......

    【讨论】:

    • 好吧,有趣的是,似乎只有一个子进程消耗了"start" 部分。但你的答案当然是正确的。
    • 所以我应该为 n 个孩子创建 n 个管道,然后向所有孩子发送“start”?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-23
    • 2022-11-15
    • 2015-09-14
    相关资源
    最近更新 更多