使用管道将字符串从两个子进程发送到其父进程时遇到问题

时间:2018-03-09 06:25:16

标签: c

我正在尝试学习用于进程间通信的管道。我的代码从主父进程创建了2个子进程,我试图使用管道将两个子进程中的字符串发送到父进程。似乎第一个孩子的字符串正确发送,但第二个孩子的字符串不是。我的计划如下:

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

int main()
{
    int pdes0[2];
    int pdes1[2];
    pipe(pdes0);
    pipe(pdes1);
    if(pdes0 < 0)
    {
        printf("Error creating pipe pdes0\n");
    }
    if(pdes1 < 0)
    {
        printf("Error creating pipe pdes1\n");
    }
    printf("Parent pid: %d\n", getpid());
    for(int i=0; i<2; i++)
    {
        if(fork() == 0)
        {
            /* child */
            if(i == 0)
            {
                /* child 0 */
                printf("Child0 pid %d from parent pid %d\n", getpid(), getppid());
                char child0[10] = "child0";
                printf("Child0: %s\n", child0);
                close(pdes0[0]);
                write(pdes0[1], child0, strlen(child0)+1);
             }
            if(i == 1)
            {
                /* child 1 */
                printf("Child1 pid %d from parent pid %d\n", getpid(), getppid());
                char child1[10] = "child1";
                printf("Child1: %s\n", child1);
                close(pdes1[0]);
                write(pdes1[1], child1, strlen(child1)+1);
            }
            exit(0);
            }
        else
        {
            /* parent */
            char inbuf0[10];
            char inbuf1[10];
            close(pdes0[1]);
            read(pdes0[0], inbuf0, 10);
            printf("Parent0 read: %s\n", inbuf0);
            close(pdes0[0]);

            close(pdes1[1]);
            read(pdes1[0], inbuf1, 10);
            printf("Parent1 read: %s\n", inbuf1);
            close(pdes1[0]);
         }

    }
    wait(NULL);
}

我得到的输出是:

Parent pid: 3181 
Child0 pid 3182 from parent pid 3181 
Child0: child0
Parent0 read: child0
Parent1 read: H?
Parent0 read: child0
Parent1 read: H?
Child1 pid 3183 from parent pid 1
Child1: child1

我也很困惑为什么child1的pid输出为1,因为在这种情况下它应该是3181。任何和所有的帮助非常感谢。提前谢谢!

1 个答案:

答案 0 :(得分:1)

错误在于您尝试从pdes0[0]pdes1[0]阅读,无论i是否等于01

此外,您将在循环的第一次运行中关闭两个描述符。当i等于1时,描述符不再有效,对read的调用将返回失败,您继续使用缓冲区,就像它们保存有效数据一样。

这是代码的父级的更新版本。

/* parent */
if ( i == 0 )
{
   char inbuf0[10];
   close(pdes0[1]);
   read(pdes0[0], inbuf0, 10);
   printf("Parent0 read: %s\n", inbuf0);
   close(pdes0[0]);
}

if ( i == 1 )
{
   char inbuf1[10];
   close(pdes1[1]);
   read(pdes1[0], inbuf1, 10);
   printf("Parent1 read: %s\n", inbuf1);
   close(pdes1[0]);
}

通过这种改变,我得到了预期的输出。

Parent pid: 7262
Child0 pid 7263 from parent pid 7262
Child0: child0
Parent0 read: child0
Child1 pid 7264 from parent pid 7262
Child1: child1
Parent1 read: child1

另外,检查

if(pdes0 < 0)

if(pdes1 < 0)

错了。在这些行中,数组衰减到int*,它们将始终评估为true。这是他们需要的:

int st0 = pipe(pdes0);
int st1 = pipe(pdes1);
if(st0 < 0)
{
   printf("Error creating pipe pdes0\n");
}
if(st1 < 0)
{
   printf("Error creating pipe pdes1\n");
}