如果只开一个管道,但是父进程不关闭读端,子进程也不关闭写端,双方都有读端和写端,为什么不能实现双向通信?
用一个管道实现双向通信是可以的,不过不灵活也没有实际的意义。
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信号量……
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
暂无简介
文章 0 评论 0
接受
发布评论
评论(1)
用一个管道实现双向通信是可以的,不过不灵活也没有实际的意义。
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信号量……