管道使用2个管道在孩子和父母之间进行通信

时间:2013-04-22 17:13:06

标签: c unix pipe

#include<dirent.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main()
{
    int canal_son[2];
    int canal_father[2];
    pipe(canal_father);
    pipe(canal_son);
    char mesaj_son[20];
    char mesaj_father[20];

    if (fork()==0)
    {
        printf("Son %d\n",getpid());
        read(canal_father[0],mesaj_father,4);
        int j;
        for(j=0;j<5;j++) 
        {
            printf("The message from father is: %s \n",mesaj_father);
            read(canal_father[0],mesaj_father,4);
            write(canal_son[1],"son",3);
        }
        exit(0);
    }

    int i=5;
    for (i=0;i<5;i++)
    {
        write(canal_father[1],"mesas",4);
        read(canal_son[0],mesaj_son,10);
        printf("we are in father:%s\n",mesaj_son);
    }
}

我想要做的是创建管道以便在孩子和父亲之间进行通信,唯一的问题是当我尝试使用两者时,我的进程冻结,就像它期待一些输入,如果我只使用一个管道, canal_father或canal_son这一切都很完美,有没有人知道使用2个管道有什么问题?

非常感谢。

3 个答案:

答案 0 :(得分:1)

你的代码的结构方式,儿子在写一个之前尝试从父亲那里读取两条消息,而父亲写一条消息然后尝试读一条消息。因此,子句在第二次读取时阻塞(循环中的一个,j = 0),而父亲在第一次读取时阻塞(i = 0)。

此外,由于你从不在任何一个过程中关闭任何写入结尾(儿子中有4个 - 2个,父亲中有2个),所以你永远不会在读取时获得任何EOF。这不是一个真正的问题,因为你永远不会等待eof,但如果你试图做更复杂的事情可能会成为一个问题。

最后,您正在编写的消息不包含字符串的终止NUL('\0'),因此当您将printf传递给它们时,它们将被终止,这将导致问题。您需要在写入的数据中包含NUL,或者从读取调用中读取长度(返回值)并明确终止字符串。

在任何情况下,都应该检查读取和写入错误的返回值。

答案 1 :(得分:1)

您正在阅读和编写不同大小,未终止的字符串并执行不同数量的读写操作。如果你使大小和读/写一致,它就可以工作。

if (fork()==0)
{
    printf("Son %d\n",getpid());
    int j;
    for(j=0;j<5;j++)
    {
        printf("The message from father is: %s \n",mesaj_father);
        read(canal_father[0],mesaj_father,6);
        write(canal_son[1],"son",4);
    }
    exit(0);
}

int i=5;
for (i=0;i<5;i++)
{
    write(canal_father[1],"mesas",6);
    read(canal_son[0],mesaj_son,4);
    printf("we are in father:%s\n",mesaj_son);
}

答案 2 :(得分:1)

您的孩子正试图从父母的管道中读取两次。结果是 孩子和父母都在等待彼此开始写作。

完整的事件序列如下:

  1. 父母写信给孩子。
  2. 孩子从父母那里读。
  3. 家长等待孩子的阅读。
  4. 孩子等待从父母那里读。
  5. 要解决此问题,请从子项开头删除额外的读取并移动打印输出 在循环中读取之后。所以子代码看起来像这样:

        printf("Son %d\n",getpid());
        int j;
        for(j=0;j<5;j++) 
        {
            read(canal_father[0],mesaj_father,4);
            printf("The message from father is: %s \n",mesaj_father);
            write(canal_son[1],"son",3);
        }
        exit(0);