单个管道可以用于父级和子级之间的2路通信吗?

问题描述 投票:0回答:5

假设我使用

pipefdn[2]
pipe()
,可以使用单个管道实现双向通信还是需要2个管道?

c unix linux-kernel operating-system pipe
5个回答
1
投票

虽然此操作在某些情况下会成功,但它不是推荐的方法,特别是在生产代码中。由于 Pipe() 默认情况下不提供任何同步机制,而且如果在其他进程的 write() 之前没有调用任何数据或 read(),则 read() 可能会无限挂起。

推荐的方法是始终使用 2 个管道。 pipeline1[2]、pipe2[2] 用于双向通信。

欲了解更多信息,请参阅以下视频说明。 https://www.youtube.com/watch?v=8Q9CPWuRC6o&list=PLfqABt5AS4FkW5mOn2Tn9ZZLLDwA3kZUY&index=11


0
投票

不抱歉。 Linux的pipe()是单向的。请参阅 手册页 ,以及 pipe(7)fifo(7)。还要考虑

AF_UNIX
套接字,请参阅 unix(7)


0
投票

如果我错了,请纠正我:但我认为你可以。问题是您可能不想这样做。首先,创建一个简单的程序:

#include <stdio.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

int pd[2];
int num = 2;
int main(){
    pid_t t = fork();
    /* create a child process */
    if(t<0){
        printf("error in fork");
        exit(1);
    }
    /* create a pipe */
    if(pipe(pd)==-1){
        printf("error in pipe");
        exit(3);
    }
    else if(t==0){
        //close(pd[1]);  // child close writing end
        int r = read(pd[0], &num, sizeof(num));
        if(r<0){
           printf("error while reading");
           exit(2);
        }
        printf("i am the child and i read %d\n",num);
      //  close(pd[0]);
        exit(0);
    }
    /* parent process */
    //close(pd[0]);   /* parents closes its reading end
    if(write(pd[1],&num,sizeof(num)<0)){
        printf("error in reading");
        exit(4);
    }
    //close(pd[1]);
    /*parent wait for your child to terminate;*/
    int status;
    wait(&status);
    printf("my child ended with status: %d\n",status);
    return 0;
}

尝试与

close()
一起玩。通过将其放在评论中或包含它来跳过它。您会发现,为了让该程序运行,唯一真正需要的系统调用关闭是子进程读取之前的系统调用。我在堆栈溢出中找到了一个答案,说“因为写端是开放的,系统会等待,因为可能会发生潜在的写操作..”。 就我个人而言,我尝试在没有它的情况下运行它,但发现它不会终止。另一个 close() 虽然是一个很好的做法,但不会影响执行。 (我不确定为什么会发生这种情况,也许更有经验的人可以帮助我们)。
现在让我们检查一下您问的问题:
我在这里可以看到一些问题: 如果两个进程在同一个通道中写入,则可能会出现竞争条件:
他们同时写入同一个文件描述符:

  • 如果一个进程读取自己的写入而不是进程的写入会怎样 它尝试与?您如何知道应该阅读文件中的哪个位置?
  • 如果一个进程写在另一个进程的“上方”怎么办?

0
投票

根据我的课本,两个进程必须有两个管道才能实现双向通信。 对于父进程和子进程来说,也应该如此。


-2
投票

是的,可以,我以前就这样做过。我让父母和孩子使用相同的两个管道向彼此发送不同的消息并正确接收它们。只要确保您始终从第一个文件描述符读取并写入第二个文件描述符即可。

© www.soinside.com 2019 - 2024. All rights reserved.