管道是什么:

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)实现全双工双向通讯相关推荐

  1. 进程间数据传递:Queue,Pipe 进程间数据共享:Manager

    进程间数据传递:Queue,Pipe 进程间数据共享:Manager 1.使用multiprocessing模块的Queue实现数据传递 ''' 进程间通讯:Queue,用法跟线程里的Queue一样, ...

  2. 命名管道(FIFO) Linux进程进程间的通信之命名管道(FIFO)

    Linux进程进程间的通信之命名管道(FIFO) 命名管道(FIFO),它和一般的管道一样.都是作为中间的邮递员来实现两个进程间的通信交流. 命名管道(FIFO)有几个特点: 1.命名管道(FIFO) ...

  3. linux无名管道实验代码,Linux 进程间通讯之创建无名管道和读写无名管道

    Linux进程间通讯的方式: 1. 管道(pipe)和有名管道(FIFO). 2. 信号(signal) 3. 消息队列 4. 共享内存 5. 信号量 6. 套接字(socket) 管道通讯: 无名管 ...

  4. 进程间基于消息队列的通信_Linux 进程间的通信方式

    (一)进程的概念 进程是操作系统的概念,每当我们执行一个程序时,对于操作系统来讲就是创建一个进程,在这个 过程中伴随着资源的分配和释放,可以认为进程是一个程序的一次执行过程. (二)进程间通信的概念 ...

  5. Liunx系统编程篇—进程通信(二)无名管道(原理、创建、实战)命名管道(原理、创建、实战)

    一.无名管道 管道,通常指无名管道(之所以叫无名管道是因为,没有文件名),是 UNIX 系统IPC最古老的形式. 特点 (1)它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端. (2) ...

  6. linux系统调用创建无名管道,无名管道系统调用

    本文关键字: linux 管道通信,linux 进程通信方式,无名管道 1.管道创建与关闭说明 管道是基于文件描述符的通信方式,当一个管道建立时,它会创建两个文件描述符fd[0]和fd[1],其中fd ...

  7. 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:  ...

  8. linux进程间通讯-无名管道

    文章目录 无名管道 无名管道的创建 -- pipe函数 无名管道的读写规律 无名管道 无名管道概述 管道(pipe)又称无名管道. 无名管道是一种特殊类型的文件,在应用层体现为两个打开的文件描述符.任 ...

  9. step4 . day7 进程间的通信方式

    进程间的通信方式: 无名管道(pipe) 有名管道 (fifo) 信号(signal) system v5的进程间通信方式 共享内存(share memory) 消息队列(message queue) ...

最新文章

  1. Atheros AR9485 ubuntu 10.04 驱动安装及networking disable问题解决
  2. Java的最新发展– 2018年4月下旬
  3. [导入]相片: 53787515.jpg
  4. 九、MySQL常见约束相关知识总结 学习笔记 + 强化复习(六大约束)
  5. jquery的扩展方法介绍
  6. mysql web备份软件_GitHub - toolzone/mysql_web_backup: mysql数据库自动备份,web网站自动备份shell脚本...
  7. TD-LTE Technology And Its Measurements(TD-LTE 技术及其应用)
  8. Android之使用枚举利弊及替代方案
  9. Workflow WF Reference Links for 2009-03-06
  10. hdu 5175 Misaki's Kiss again
  11. Android编码规范05
  12. Substance Designer中Histogram相关节点理解
  13. 如何理解混淆矩阵,以及预测少数类的评估指标?
  14. bzoj 1606 购买干草
  15. 配置sumlime html,Sublime Text 3使用SublimeLinter配置JS,CSS,HTML语法检查
  16. oracle收购了什么意思,BEA为何会被Oracle收购?
  17. C:\Users\zhen\AppData\Local\Android\Sdk\platform-tools\adb'' finished with non-zero exit value 1
  18. flv 文件格式解析
  19. 智能设备时代的个人生命安全
  20. Sleep tight:(晚上) 睡个好觉!

热门文章

  1. 对校招生培养工作的建议_对招生工作的建议和意见
  2. 哪个国家拥有全世界最牛逼的程序员?
  3. 什么是响应式设计?响应式设计的基本原理是什么?如何兼容低版本的 IE?
  4. 《论文阅读》Multi-Granularity Reference-Aided Attentive Feature Aggregation for Video-based Person Re-iden
  5. 芒果TV——百变大咖秀爬虫与数据可视化
  6. linux下载clang7,clang,linux_ubuntu安装clang依赖报错, 如果降版本安装?,clang,linux - phpStudy...
  7. 时间序列学习(1)——【时间序列初认识】
  8. 代码千万别写太长了!
  9. 如何选择漏电保护器规格型号_漏电保护器型号有哪些 漏电保护器选购技巧
  10. 没有ldf文件的数据库附加