Linux-父进程和子进程能不能通过一个管道实现双向通信?

发布于 2017-07-30 12:14:44 字数 59 浏览 1588 评论 1

如果只开一个管道,但是父进程不关闭读端,子进程也不关闭写端,双方都有读端和写端,为什么不能实现双向通信?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜无邪 2017-07-31 15:10:56

用一个管道实现双向通信是可以的,不过不灵活也没有实际的意义。

pipe()的到的两个fd分别是管道的读端和写端,管道底层是一个缓冲区,读写都在这个缓冲区里进行。如果子进程向管道里写入数据,这个数据可能被父进程读到,也可能被子进程自己读到,要怎么区分这种情况呢?

自定义一个协议区分消息发送目标,接受消息时如果不是自己应该接收的就再发回去
用文件锁来协调两个进程对管道的读写
用sleep碰运气
...

这也太折腾了吧,就像在多线程程序里协调对共享变量的读写一样,麻烦而且易错。

最后写一个简单的程序,在父子进程间传递一个递增的整数。

#include <stdio.h>
#include <unistd.h>
#include <sys/file.h> // flock

// 父子进程执行同样的操作
void operate(int fds[2], const char *name) {
int send_num = -1, recv_num = 0;
int rfd = fds[0], wfd = fds[1];
int lock = open("./lock", O_CREAT, S_IRWXU);

while (1) {
flock(lock, LOCK_EX);
read(rfd, &recv_num, sizeof(int));

if (recv_num == send_num) { //重发
write(wfd, &recv_num, sizeof(int));
flock(lock, LOCK_UN);
usleep(1000); // 碰运气
continue;
}
send_num = recv_num + 1;
write(wfd, &send_num, sizeof(int));
printf("%s %dn", name, send_num);
flock(lock, LOCK_UN);
}
}

int main(int argc, char *argv[])
{
int fds[2], n = 0;
pipe(fds);
write(fds[1], &n, sizeof(int));
if (fork()) {
operate(fds, "Parent");
} else {
operate(fds, "Child ");
}
return 0;
}

有了锁之后,实现更复杂的功能应该也是可以的,写完才想起还可以用SysV信号量……

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文