pipe 半双工_linux进程间通信之管道(无名管道pipe)实现全双工双向通信
管道是什么:
1. 管道只能用于具有亲缘关系的进程之间通信。
2.管道是一种单工或者说半双工的通信方式,传递信息的方向是固定的,只能由一端传递到另一端。
头文件及函数原型:
#include
int pipe(int fd[2]);
当用pipe 创建管道后,两个文件描述符fd[0],fd[1]就可以使用了,其中fd[0]用于读取,fd[1]用于写入。调用管道pipe返回值0表示成功,返回值-1表示失败。
pipe函数创建管道后,接着fork出子进程,子进程继承父进程管道。
代码举例来看:
#include
#include
#include
#include
#include
#define MAX_DATA_LEN 256
#define DELAY_TIME 1
int main() {
pid_t pid;
char buf[MAX_DATA_LEN];
const char *data="Pipe Test";
int real_read,real_write;
int pipe_fd[2];
memset((void*)buf,0,sizeof(buf));
if(pipe(pipe_fd)<0){
perror("Pipe create error!\n");
exit(1);
}
if ((pid=fork())<0) {
perror("Fork error!\n");
exit(1);
} else if (pid==0) {
close(pipe_fd[1]);
sleep(DELAY_TIME*3);
if ((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) {
printf("Child receive %d bytes from pipe: '%s'.\n",real_read,buf);
}
close(pipe_fd[0]);
exit(0);
} else {
close(pipe_fd[0]);
sleep(DELAY_TIME);
if ((real_write=write(pipe_fd[1],data,strlen(data)))>0) {
printf("Parent write %d bytes into pipe: '%s'.\n",real_write,data);
}
close(pipe_fd[1]);
waitpid(pid,NULL,0);
exit(0);
}
}
复制代码
运行输出:
Parent write 9 bytes into pipe: 'Pipe Test'.
Child receive 9 bytes from pipe: 'Pipe Test'.
上述代码只能从父进程向子进程传递,如何从子进程向父进程传递呢?我们看到父进程关闭了管道读取端“close(pipe_fd[0]);”,子进程关闭了管道写入端“close(pipe_fd[1]);”,如果取消关闭这两个端,是否能够实现子进程向父进程传递呢。
父进程先发送,子进程接收,然后子进程再发送,父进程再接收,实现全双工互相通信,期望运行结果如下:
Parent write 9 bytes into pipe: 'Pipe Test'.
Child receive 9 bytes from pipe: 'Pipe Test'.
Child write 9 bytes from pipe: 'Pipe Test'.
Parent receive 9 bytes from pipe: 'Pipe Test'.
修改代码如下:
#include
#include
#include
#include
#include
#define MAX_DATA_LEN 256
#define DELAY_TIME 1
int main() {
pid_t pid;
char buf[MAX_DATA_LEN];
const char *data="Pipe Test";
int real_read,real_write;
int pipe_fd[2];
memset((void*)buf,0,sizeof(buf));
if(pipe(pipe_fd)<0){
perror("Pipe create error!\n");
exit(1);
}
if ((pid=fork())<0) {
perror("Fork error!\n");
exit(1);
} else if (pid==0) {
//close(pipe_fd[1]);
sleep(DELAY_TIME*3);
if ((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) {
printf("Child receive %d bytes from pipe: '%s'.\n",real_read,buf);
}
if ((real_write=write(pipe_fd[1],data,strlen(data)))>0) {
printf("Child write %d bytes into pipe: '%s'.\n",real_write,data);
}
close(pipe_fd[0]);
exit(0);
} else {
//close(pipe_fd[0]);
sleep(DELAY_TIME);
if ((real_write=write(pipe_fd[1],data,strlen(data)))>0) {
printf("Parent write %d bytes into pipe: '%s'.\n",real_write,data);
}
if ((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) {
printf("Parent receive %d bytes from pipe: '%s'.\n",real_read,buf);
}
close(pipe_fd[1]);
waitpid(pid,NULL,0);
exit(0);
}
}
复制代码
但是实际运行如下:
Parent write 9 bytes into pipe: 'Pipe Test'.
Parent receive 9 bytes from pipe: 'Pipe Test'.
可以看到,父进程发送的数据被父进程自己接收了,子进程读不到数据被阻塞了。显然这种方法不行。
因为管道是单工的,只能固定从一个方向传递到另一个方向。
要实现互相通信,一个管道是不行的,可以创建两个管道,一个管道是父写子读,另一个是子写父读。
代码如下:
#include
#include
#include
#include
#include
#define MAX_DATA_LEN 256
#define DELAY_TIME 1
int main() {
pid_t pid;
char buf[MAX_DATA_LEN];
const char *data="Pipe Test";
int real_read,real_write;
int pipe_fd[2],pipe_fd2[2];
memset((void*)buf,0,sizeof(buf));
if(pipe(pipe_fd)<0){
perror("Pipe create error!\n");
exit(1);
}
if(pipe(pipe_fd2)<0){
perror("Pipe create error!\n");
exit(1);
}
if ((pid=fork())<0) {
perror("Fork error!\n");
exit(1);
} else if (pid==0) {
close(pipe_fd[1]);
close(pipe_fd2[0]);
sleep(DELAY_TIME*3);
if ((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) {
printf("Child receive %d bytes from pipe: '%s'.\n",real_read,buf);
}
if ((real_write=write(pipe_fd2[1],data,strlen(data)))>0) {
printf("Child write %d bytes into pipe: '%s'.\n",real_write,data);
}
close(pipe_fd[0]);
close(pipe_fd2[1]);
exit(0);
} else {
close(pipe_fd[0]);
close(pipe_fd2[1]);
sleep(DELAY_TIME);
if ((real_write=write(pipe_fd[1],data,strlen(data)))>0) {
printf("Parent write %d bytes into pipe: '%s'.\n",real_write,data);
}
if ((real_read=read(pipe_fd2[0],buf,MAX_DATA_LEN))>0) {
printf("Parent receive %d bytes from pipe: '%s'.\n",real_read,buf);
}
close(pipe_fd[1]);
close(pipe_fd2[0]);
waitpid(pid,NULL,0);
exit(0);
}
}
复制代码
运行结果:
Parent write 9 bytes into pipe: 'Pipe Test'.
Child receive 9 bytes from pipe: 'Pipe Test'.
Child write 9 bytes into pipe: 'Pipe Test'.
Parent receive 9 bytes from pipe: 'Pipe Test'.
可以看到,创建了两个管道 “int pipe_fd[2],pipe_fd2[2];”,
pipe_fd 是父写子读,pipe_fd2是子写父读,通过两个管道,实现了进程的全双工互相通信。
pipe 半双工_linux进程间通信之管道(无名管道pipe)实现全双工双向通信相关推荐
- pipe 半双工_linux进程间通讯之管道(无名管道pipe)实现全双工双向通讯
管道是什么: 1. 管道只能用于具备亲缘关系的进程之间通讯. 2.管道是一种单工或者说半双工的通讯方式,传递信息的方向是固定的,只能由一端传递到另外一端. 头文件及函数原型: #include int ...
- linux 进程间通信及makefile 无名管道/有名管道/共享内存/信号/消息队列
http://www.voidcn.com/article/p-hxvuiypm-mr.html https://www.cnblogs.com/wuyida/archive/2013/02/03/6 ...
- linux系统调用创建无名管道,无名管道系统调用
本文关键字: linux 管道通信,linux 进程通信方式,无名管道 1.管道创建与关闭说明 管道是基于文件描述符的通信方式,当一个管道建立时,它会创建两个文件描述符fd[0]和fd[1],其中fd ...
- Linux系统无名管道通信实验,Linux进程间通信(二)---管道通信之无名管道及其基础实验...
管道简介 管道是Linux中进程间通信的一种方式,它把一个程序的输出直接连接到另一个程序的输入(其实我更愿意将管道比喻为农村浇地的管子).Linux的管道主要包括两种:无名管道和有名管道.这一节主要讲 ...
- 进程间通信方式(一)-- 无名管道、有名管道
文章目录 1. 进程间通信方式分类 2. 进程间通信实现方式 3. 无名管道 3.1 概念 3.2 相关函数 读写规律 3.3 无名管道实现进程间通信 4. 有名管道 4.1 概念 4.2 创建有名管 ...
- linux进程间通信(IPC) ---无名管道
管道概述 管道(pipe)又称无名管道 无名管道是一种特殊类型的文件,在应用层体现为两个打开的文件描述符 任何一个进程在创建的时候,系统都会,给它分配4G的虚拟内存,分为3G的用户空间和1G的内核空间 ...
- linux进程间通讯-无名管道
文章目录 无名管道 无名管道的创建 -- pipe函数 无名管道的读写规律 无名管道 无名管道概述 管道(pipe)又称无名管道. 无名管道是一种特殊类型的文件,在应用层体现为两个打开的文件描述符.任 ...
- 进程间的通信--无名管道
无名管道是 UNIX 系统 IPC(进程间通信)的最古老形式,所有 UNIX 系统都支持这种通信方式机制 管道的特点: 半双工,数据在同一时刻只能在一个方向上流懂 数据只能从管道的一段写入,另一端读出 ...
- 【Linux】管道文件(有名管道、无名管道)
[Linux]管道文件(有名管道.无名管道) 多进程编程的目的就是为了同时完成多个任务. 例如:一个产品,一个软件,需要n个进程同时执行才能完成,而这些进程之间一定是有所联系的. 因此:多进程工作时, ...
- Linux有名管道与无名管道简介
无名管道 无名管道是最古老的进程通信方式, 有如下两个特点: 1. 只能用于有关联的进程间数据交互, 如父子进程, 兄弟进程, 子孙进程, 在目录中看不到文件节点, 读写文件描述符存在一个 int 型 ...
最新文章
- python下线程以及锁
- Python学习并发与多线程
- 网关和路由器的区别_工业网关和工业路由器的区别?
- 最全面的JVM G1学习笔记
- JS partial-application
- [转]Android 代码混淆和加固 so库 简单教你一行代码实现
- java中字母用什么单词赋值_Java初学
- css根据屏幕大小切换样式
- UVA10917 Walk Through the Forest
- 移动端数据爬取和Scrapy框架
- libjpeg-turbo 2.1.2 交叉编译
- 一阶低通滤波器方程_一阶低通滤波器
- NLTK2:词性标注
- linux gcc getch,模拟实现getch()
- 电商大数据应用之用户画像
- Linux使用grep查找文件内容
- 模拟科目二倒车入库训练
- C#开发金蝶K3插件
- layui upload上传文件时动态设置headers参数值
- 若依管理系统RuoYi-Vue(前后端分离版)项目启动教程
热门文章
- count(1)、count(*)、count(列名) 详解
- SAP中生产返工中单独的作业返冲处理分析测试
- 智能优化算法应用:基于麻雀搜索优化K-means图像分割算法 - 附代码
- 斯科特.H.杨:MIT 课程挑战者 __转
- netbeans11安装教程_Netbeans使用教程
- 扫描技术的原理与应用(Nmap使用)
- mysql insert on duplicate_一条Insert on duplicate引发的血案
- php实现加密解密,PHP实现的加密解密处理类
- 台湾嵌入式软硬件厂商组建联盟 欲分Gphone一杯羹
- asp内乱码,注意不是ajax