为啥在并行子进程之间分叉两次后 pipe() 不工作?

Posted

技术标签:

【中文标题】为啥在并行子进程之间分叉两次后 pipe() 不工作?【英文标题】:Why isn't pipe() working after forking twice between parallel child processes?为什么在并行子进程之间分叉两次后 pipe() 不工作? 【发布时间】:2018-01-29 18:06:50 【问题描述】:

我的目标是将字符串从一个子进程发送到另一个子进程。我在父进程中设置了一个管道,然后分叉了两次。两个到达的语句都打印了,为什么管道消息没有?

#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<string.h>
int main (char * argv[], int argc)

int arr[2];
pipe(arr);

int id = 0;
int pid = fork();
id = 1;
if(pid > 0) pid = fork();

if(pid > 0)

    close(arr[0]);
    close(arr[1]);
    wait(NULL);

else if (id == 0)

    close(arr[0]);
    char message[] = "HYPERTEXT TRANSFER\n";
    write(arr[1],message,strlen(message)+1);
    printf("reached\n");

else if(id == 1)

    printf("reached\n");
    close(arr[1]);
    char * buf = malloc (sizeof(char)* 20);
    read(arr[0], buf, 20);
    printf("%s", buf);



return 0;

程序输出“reached”两次。

【问题讨论】:

id 对于所有进程都是 1。你不会进入else if (id == 0) 写任何东西。 id = 1 应该在 if (pid &gt; 0) 内,因此第一个孩子不会是这样。 【参考方案1】:

id 对于所有进程都是 1。您不会进入 else if (id == 0) 写入任何内容,因此,您正在尝试从空管道中读取。

【讨论】:

你确定是这样吗?我应该澄清程序输出“达到”两次。 你是对的,当冷却时间到了我会接受这个答案。【参考方案2】:

您的问题是,对于您的两个子进程,id = 1。实际上,两个子进程都执行id = 1 行,因此它们都是接收者。

试试:

#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<string.h>
int main (char * argv[], int argc)

int arr[2];
pipe(arr);

int id = 0;
int pid = fork();

if(pid > 0) 
    pid = fork();
    id = 1; // Here only the second child process (and the parent process, but who cares) have id == 1.


if(pid > 0)

    close(arr[0]);
    close(arr[1]);
    wait(NULL);

else if (id == 0)

    close(arr[0]);
    char message[] = "HYPERTEXT TRANSFER\n";
    write(arr[1],message,strlen(message)+1);
    printf("reached\n");

else if(id == 1)

    printf("reached\n");
    close(arr[1]);
    char * buf = malloc (sizeof(char)* 20);
    read(arr[0], buf, 20);
    printf("%s", buf);



return 0;

【讨论】:

以上是关于为啥在并行子进程之间分叉两次后 pipe() 不工作?的主要内容,如果未能解决你的问题,请参考以下文章

linux下fork两子进程为啥只有一个读取到pipe的内容?

Unix环境高级编程fork函数总结

如何在父进程和子进程之间发送带有 pipe() 的矩阵?

同一父进程下的子进程之间的通信(pipe通信)

如何在分叉进程中处理套接字连接

为啥 RecyclerView 项目在点击两次后才改变背景颜色?