我对半双工,全双工的理解其实他们只是一个工作模式
为什么呢?
道理很简单假设我们使用管道通讯来进行进程间的通讯他只是一个信息的载体,而我们对他的使用方法才是确定他是全双工还是半双工的真正来源.所以这里的重点并不是载体,而是使用方法.
我把这些载体比喻成一个管子,管子内的水比喻成信息.那么我们正常使用一个管子传导水流即是信息的传递.
这时我们就会有两种使用场景.
1.只有一根管子P,有两个桶AB,那么我可以用管子给A导水,同时用B接水,反之也是可行的.不可行的是我A给B导水的同时B还给A导水,或者A给B导水的同时A还给还从管子里抽水导水,我们可以这么做,但是谁也不会这么做.这就是半双工.
2.当我有两个管子P,Q时就好办了,我们可以我们用P从A给B的同时,还可以用Q从B导水.这是可行的!而写水流无序信息有序!这样做才是最安全的!这就是全双工.
下面附上图解和一段pipe的半双工通讯的示例代码表示思路.有了思路全双工的代码其实也不难.
半双工
全双工
pipe的半双工实现图例
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
int fd[2];
pid_t child;
char *father_massage = "father massage";
char *child_massage = "child massage";
char child_buf[25] = {0};
char father_buf[25] = {0};
int main()
{
if( -1 == pipe(fd))
{
perror("Make pipe fail");
exit(0);
}
child = fork();
if(0 > child)
{
perror("Create child process fail:");
exit(0);
}
else if(0 == child)
{
write(fd[2], child_massage, strlen(child_massage));
printf("i'm child, i was send a message to my father: %s\n", child_massage);
sleep(1);
read(fd[1], child_buf, 25);
printf("i'm child, i was recive a message from my father: %s\n", child_buf);
}
else
{
read(fd[1], father_buf, 25); //阻塞等待孩子写管道
printf("i'm father, i was recive a message from my child: %s\n", father_buf);
write(fd[2], father_massage, strlen(father_massage)); //孩子给了1秒时间让父亲读完管道写管道
printf("i'm child, i was send a message to my father: %s\n", father_massage);
sleep(2); //休眠2秒等孩子进程退出,防止孩子被拐卖给init
}
return 0;
}