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'.spa
上述代码只能从父进程向子进程传递,如何从子进程向父进程传递呢?咱们看到父进程关闭了管道读取端“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'.
修改代码以下:
code
#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是子写父读,经过两个管道,实现了进程的全双工互相通讯。ip
pipe 半双工_linux进程间通讯之管道(无名管道pipe)实现全双工双向通讯相关推荐
- 进程间数据传递:Queue,Pipe 进程间数据共享:Manager
进程间数据传递:Queue,Pipe 进程间数据共享:Manager 1.使用multiprocessing模块的Queue实现数据传递 ''' 进程间通讯:Queue,用法跟线程里的Queue一样, ...
- 命名管道(FIFO) Linux进程进程间的通信之命名管道(FIFO)
Linux进程进程间的通信之命名管道(FIFO) 命名管道(FIFO),它和一般的管道一样.都是作为中间的邮递员来实现两个进程间的通信交流. 命名管道(FIFO)有几个特点: 1.命名管道(FIFO) ...
- linux无名管道实验代码,Linux 进程间通讯之创建无名管道和读写无名管道
Linux进程间通讯的方式: 1. 管道(pipe)和有名管道(FIFO). 2. 信号(signal) 3. 消息队列 4. 共享内存 5. 信号量 6. 套接字(socket) 管道通讯: 无名管 ...
- 进程间基于消息队列的通信_Linux 进程间的通信方式
(一)进程的概念 进程是操作系统的概念,每当我们执行一个程序时,对于操作系统来讲就是创建一个进程,在这个 过程中伴随着资源的分配和释放,可以认为进程是一个程序的一次执行过程. (二)进程间通信的概念 ...
- Liunx系统编程篇—进程通信(二)无名管道(原理、创建、实战)命名管道(原理、创建、实战)
一.无名管道 管道,通常指无名管道(之所以叫无名管道是因为,没有文件名),是 UNIX 系统IPC最古老的形式. 特点 (1)它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端. (2) ...
- linux系统调用创建无名管道,无名管道系统调用
本文关键字: linux 管道通信,linux 进程通信方式,无名管道 1.管道创建与关闭说明 管道是基于文件描述符的通信方式,当一个管道建立时,它会创建两个文件描述符fd[0]和fd[1],其中fd ...
- mysql数据给mes_PLC通讯智能网关:MES服务对接,SQL数据库双向通讯,HTTP协议GET/POST请求,MQTT协议JSON发布/订阅...
常用的PLC型号系列:相关软件手册等资料下载 ◆ FX: 三菱FX 系列PLC ◆ QL: 三菱Q/L/R 系列PLC ◆ AS: 三菱A 系列PLC ◆ OM: 欧姆龙全系列PLC ◆ S72S: ...
- linux进程间通讯-无名管道
文章目录 无名管道 无名管道的创建 -- pipe函数 无名管道的读写规律 无名管道 无名管道概述 管道(pipe)又称无名管道. 无名管道是一种特殊类型的文件,在应用层体现为两个打开的文件描述符.任 ...
- step4 . day7 进程间的通信方式
进程间的通信方式: 无名管道(pipe) 有名管道 (fifo) 信号(signal) system v5的进程间通信方式 共享内存(share memory) 消息队列(message queue) ...
最新文章
- Atheros AR9485 ubuntu 10.04 驱动安装及networking disable问题解决
- Java的最新发展– 2018年4月下旬
- [导入]相片: 53787515.jpg
- 九、MySQL常见约束相关知识总结 学习笔记 + 强化复习(六大约束)
- jquery的扩展方法介绍
- mysql web备份软件_GitHub - toolzone/mysql_web_backup: mysql数据库自动备份,web网站自动备份shell脚本...
- TD-LTE Technology And Its Measurements(TD-LTE 技术及其应用)
- Android之使用枚举利弊及替代方案
- Workflow WF Reference Links for 2009-03-06
- hdu 5175 Misaki's Kiss again
- Android编码规范05
- Substance Designer中Histogram相关节点理解
- 如何理解混淆矩阵,以及预测少数类的评估指标?
- bzoj 1606 购买干草
- 配置sumlime html,Sublime Text 3使用SublimeLinter配置JS,CSS,HTML语法检查
- oracle收购了什么意思,BEA为何会被Oracle收购?
- C:\Users\zhen\AppData\Local\Android\Sdk\platform-tools\adb'' finished with non-zero exit value 1
- flv 文件格式解析
- 智能设备时代的个人生命安全
- Sleep tight:(晚上) 睡个好觉!
热门文章
- 对校招生培养工作的建议_对招生工作的建议和意见
- 哪个国家拥有全世界最牛逼的程序员?
- 什么是响应式设计?响应式设计的基本原理是什么?如何兼容低版本的 IE?
- 《论文阅读》Multi-Granularity Reference-Aided Attentive Feature Aggregation for Video-based Person Re-iden
- 芒果TV——百变大咖秀爬虫与数据可视化
- linux下载clang7,clang,linux_ubuntu安装clang依赖报错, 如果降版本安装?,clang,linux - phpStudy...
- 时间序列学习(1)——【时间序列初认识】
- 代码千万别写太长了!
- 如何选择漏电保护器规格型号_漏电保护器型号有哪些 漏电保护器选购技巧
- 没有ldf文件的数据库附加