1.管道的特点

(1)无论有名还是无名,写入管道的数据都在内存中。
(2)管道是一种半双工通信方式(通信方式有单工(固定接收方发送方,接收方只能接收,发送方只能发送)、半双工(如同对讲机,两端可以切换写入和接收)、全双工(每端都可以接收和写入,且可以同时进行))。
(3)有名和无名管道的区别:有名可以在任意进程间使用,而无名只能在父子进程间。
(4)对于管道,我们只能以只读打开或者只写打开。
(5)有名管道得需要读和写都打开,否则只以读打开或者只以写打开都会阻塞。
(6)管道中没有数据时,读管道read会发生阻塞,直至管道被写入数据,读出数据,再次阻塞。如果写端被关闭,读端read返回值会成为0。如果读端被关闭,写端向管道写入数据后会自动退出。
(7)管道写满后,写端会阻塞。
(8)由于管道的数据都在内存中,所以查看管道大小总是0。
管道的实现:

写入从头指针开始,读取从尾指针开始。写入之后,头指针挪动,读取之后尾指针挪动。如果是头指针赶上尾指针,那么管道被写满,写就会被阻塞。如果是尾指针赶上头指针,那么管道为空,read阻塞。
管道可以用来在两个进程之间传递数据,如: ps -ef | grep “bash”, 其中‘|’就是管道,其作用就是将 ps 命令的结果写入管道文件,然后 grep 再从管道文件中读出该数据进行过滤。
管道大小是可以查看的,如下图可以看到管道512字节为一个单位,乘以8就是整个管道大小。

2.有名管道

2.1有名管道的创建和头文件

有名管道可以在任意两个进程之间通信
有名管道的创建:
(1)命令创建: mkfifo + 管道名
(2)系统调用创建

#include <sys/types.h>
#include <sys/stat.h>
//filename 是管道名 mode 是创建的文件访问权限
int mkfifo( const char *filename, mode_t mode);

2.2有名管道的使用

进程 a 从键盘获取的数据循环传递给另一个进程 b。
我们可以用创建一个文件,a从键盘获取字符串存放到文件中,b从文件中读取。但是文件是存在磁盘上的,速度没有管道快,而且从文件读不到数据不会等待,但是管道不一样,b从管道读不到数据会阻塞,直到a又向管道中写入数据。

首先用命令mkfifo+管道名称创建管道

写端代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<fcntl.h>
#include<sys/stat.h>int main()
{int fd = open("fifo",O_WRONLY);assert(fd != -1);printf("open FIFO success\n");while(1){printf("please input:\n");char buff[128] = {0};fgets(buff,128,stdin);write(fd,buff,strlen(buff)-1);if(strncmp(buff,"end",3)==0){break;}}close(fd);exit(0);
}

读端代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<fcntl.h>
#include<sys/stat.h>int main()
{int fd = open("fifo",O_RDONLY);assert(fd != -1);printf("FIFO open success\n");while(1){char buff[128] = {0};int n = read(fd,buff,127);if(n <= 0 || (strncmp(buff, "end", 3)==0)){break;}printf("%s\n",buff);}close(fd);exit(0);
}

(1)如果读端或者写端先打开,那么将会在open阻塞住 ,直至另一端也打开管道。
(2)写端和读端都打开后,读端会在read处阻塞,写端向管道中写入数据后,读端才正常执行read,执行完继续在read阻塞。
(3)如果读端关闭,写端在向管道输入数据后会触发信号(SIGPIPE)自动退出。
(4)如果写端关闭,读端read函数值会返回0。
当写端和读端都在打开着,管道中的数据如果没有及时读出,不会消失。比如将读端加上休眠10s,代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>
#include<fcntl.h>
#include<sys/stat.h>int main()
{int fd = open("fifo",O_RDONLY);assert(fd != -1);printf("FIFO open success\n");while(1){char buff[128] = {0};int n = read(fd,buff,127);if(n <= 0 || (strncmp(buff, "end", 3)==0)){break;}printf("%s\n",buff);sleep(10);}close(fd);exit(0);
}

写端和读端执行情况:


发现,在读端还没来得及读走管道数据的时候写端再次向管道写入数据,管道中没读走的数据会被读端下一次读走。

3.无名管道

无名管道主要应用于父子进程间的通信。
无名管道的创建:

#include <unistd.h>
2. /*
3. pipe()成功返回 0,失败返回-1
4. fds[0]是管道读端的描述符
5. fds[1]是管道写端的描述符
6. */
7. int pipe( int fds[2]);

代码演示:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<assert.h>int main()
{int fd[2];int res = pipe(fd);assert(res != -1);pid_t pid = fork();assert(pid != -1);if(pid == 0){close(fd[1]);char buff[128] = {0};read(fd[0],buff,127);printf("child read:%s\n",buff);close(fd[0]);}else{close(fd[0]);char buff[128] = {0};printf("please input(less 128):\n");fgets(buff,128,stdin);write(fd[1],buff,strlen(buff)-1);close(fd[1]);}exit(0);
}

执行结果:

进程间通信(IPC机制)——管道相关推荐

  1. Linux系统编程---4(进程间通信IPC,管道)

    进程间通信目的 数据传输:一个进程需要将它的数据发送给另一个进程 资源共享:多个进程之间共享同样的资源. 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止 时 ...

  2. Linux 进程间通信-IPC 机制

    Linux 平台上在 Kernel 协调下完成进程之间的相互通信,有多种进程间通信 -- Inter Process Communication(IPC)方式. 1. IPC 分类 按照功能用途来看有 ...

  3. 3,进程间通信IPC机制,线程,线程通信,互斥锁

    今日内容: 1,进程间的相互通信 2,生产者消费者模型 3,线程 4,线程间通信 5,线程互斥锁 1,进程间相互通信 IPC 机制 1,基于队列来实现通信Queue,队列就相当于管道+锁 队列:先进先 ...

  4. linux进程间通信(IPC) ---无名管道

    管道概述 管道(pipe)又称无名管道 无名管道是一种特殊类型的文件,在应用层体现为两个打开的文件描述符 任何一个进程在创建的时候,系统都会,给它分配4G的虚拟内存,分为3G的用户空间和1G的内核空间 ...

  5. linux操作系统进程间通信IPC之管道pipe及FIFO

    linux环境下,各进程相互独立,如果想要交换两个进程之间的数据,需要通过内核,在内存中提供一个缓存区,一个进程往缓存区中写数据,一个往缓存区读数据,内核提供的这种机制称为进程间通信(IPC),常见的 ...

  6. 进程间通信IPC(一)(半双工管道和消息队列)

    引言: 之前学习的进程之间交换信息的方法只能由fork或exec传送打开文件,或者文件系统.但是这种通讯方式有局限性,接下来将说明进程之间相互通信的其他技术--IPC(InterProcessComm ...

  7. Linux的IPC机制(二):Socket/管道/消息队伍/信号量

    每个进程的用户地址空间都是独立的,一般而言是不能互相访问的,但内核空间是每个进程都共享的,所以进程之间要通信必须通过内核. Linux 内核提供了不少进程间通信的机制,我们来一起瞧瞧有哪些? 管道 如 ...

  8. Linux C编程--进程间通信(IPC)5--System V IPC 机制1--消息队列

    System V IPC 机制 1.基本概念 IPC对象一经创建,系统内核即为该对象分配相关的数据结构.为方便对IPC对象的管理,Linux提供了专门的IPC控制命令,主要包括查看IPC对象信息的ip ...

  9. Android中的进程间通信(IPC机制)

    记得上次阿里电话面试就问,Android中的进程间通信有哪些?当时没怎么总结过,就只说了一个AIDL.今天就来总结总结吧. 什么是进程间通信? 顾名思义,两个进程之间进行数据交换的过程,那什么又是进程 ...

  10. Binder相关面试总结(一):为什么Android要采用Binder作为IPC机制?

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nwy9SoNo-1609925310525)(//upload-images.jianshu.io/upload_ima ...

最新文章

  1. hdu2037今年暑假不AC
  2. 【原创】backbone1.1.0源码解析之Events
  3. linux 查看内核属性,怎么查看linux操作系统
  4. Educational Codeforces Round 37-F.SUM and REPLACE (线段树,线性筛,收敛函数)
  5. 《Ansible权威指南 》一第2章 Ansible基础元素介绍
  6. 保护亿万数据安全,Spring有“声明式事务”绝招
  7. 【kafka】kafka 启动 KafkaController 相关源码分析
  8. 责任分配矩阵和raci的区别_PyTorch学习笔记——repeat()和expand()区别
  9. 【BZOJ】1579: [Usaco2009 Feb]Revamping Trails 道路升级
  10. java replace三个参数_javascript replace()第二个参数为函数时的参数用法
  11. 2020神舟几号发射_xuex:2020北师大版三年级数学下册除法练习题神舟一号发射时间...
  12. 怎么推广“外卖CPS项目”赚佣金?(饿了么美团外卖红包小程序搭建教程)
  13. 通过搭建FTP站点实现上传与下载
  14. 配置ip地址常用命令及解释
  15. 拿到项目的 基本流程
  16. markdown/md文件只读权限修改
  17. 史上最详细springboot vue UEditor整合(包括遇到的各种坑)
  18. linux下tar.bz2文件的 解压缩方法
  19. Pycharm浏览器打开报错解决
  20. 在java中画背景图片_JAVA如何添加背景图片?

热门文章

  1. 位移运算符(7个)之第一个: 左移
  2. 【python数据挖掘课程】二十四.KMeans文本聚类分析互动百科语料
  3. [Android] 给图像添加相框、圆形圆角显示图片、图像合成知识
  4. 【数据结构与算法】之深入解析“地图分析”的求解思路与算法示例
  5. 2 0 2 0 年 第 十 一 届 蓝 桥 杯 - 省赛 - Python大学组 - A. 门牌制作
  6. 深入理解python中的select模块
  7. 【机器视觉】 endfor算子
  8. 【Linux】一步一步学Linux——fc命令(224)
  9. 【Linux】一步一步学Linux——builtin命令(215)
  10. 【Linux基础】kiickstart无人值守安装