半双工管道只能一端写一端读逻辑清晰,但是全双工管道两端都可读可写,某些逻辑可能不那么清晰,比如两端同时写的时候数据是否相互会覆盖?下面验证这个问题,父进程和子进程同时写一个全双工管道socketpair并且都等待对方写完以后才读取数据。这里用了三个管道,一个全双工管道socketpair和两个半双工管道,全双工管道用于父子进程同时读同时写,半双工管道用于父子进程通知对方本方已经写了全双工管道。
#include<unistd.h> #include<sys/types.h> #include<sys/socket.h> #include<cstring> #include<stdlib.h> #include<sys/wait.h> #include<iostream> #include<assert.h> using namespace std; int main(){ int fd_pc[2];//父进程通知子进程:父进程已经写了 int fd_cp[2];//子进程通知父进程:子进程已经写了 int pipefd[2];//全双工管道 int ret=pipe(fd_pc); assert(ret!=-1); ret=pipe(fd_cp); assert(ret!=-1); ret=socketpair(AF_UNIX,SOCK_STREAM,0,pipefd);//socketpair assert(ret!=-1); int pid=fork(); if(pid<0){ cout<<"fork error"<<endl; } else if(pid==0){//子进程 close(pipefd[0]); close(fd_pc[1]); close(fd_cp[0]); char* data="child write socketpair"; write(pipefd[1],data,strlen(data));//向全双工管道1端写数据 write(fd_cp[1],"y",1);//子进程通过管道fd_cp写端写入y通知父进程:子进程已经写了socketpair的1端 char buffer[5]; read(fd_pc[0],buffer,2);//读取fd_pc管道查看是否父进程写了socketpair的0端 if(buffer[0]=='y'){ char s[30]; read(pipefd[1],s,sizeof(s));//获取socketpair的1端数据(该数据由父进程发送) cout<<"child get socketpair$$ "<<s<<endl; exit(0); } else{ cout<<"child not get sockerpair"<<endl; exit(1); } } else{ close(fd_pc[0]); close(fd_cp[1]); close(pipefd[1]); char* data="parent write socketpair"; write(pipefd[0],data,strlen(data));//父进程写socketpair的0端 write(fd_pc[1],"y",1);//父进程通过管道fd_pc写端写入y通知子进程:父进程已经写了socketpair的0端 char buffer[5]; read(fd_cp[0],buffer,2);//读取fd_cp管道查看子进程是否写了socketpair的1端 if(buffer[0]=='y'){ char s[30]; read(pipefd[0],s,sizeof(s));//读取socketpair的0端(该数据由子进程发送) cout<<"parent get socketpair$$ "<<s<<endl; waitpid(pid,NULL,0); } else{ cout<<"child not get socketpair"<<endl; return 1; } } return 0; }
父子进程同时写了socketpair并且都等待对方写完才读取socketpair,结果表明父子进程即使同时写了sockepair它们的数据不会相互覆盖,可见全双工管道底层实现逻辑类似用两个半双工管道模拟的。