博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
进程间通信(2)--管道
阅读量:4185 次
发布时间:2019-05-26

本文共 1224 字,大约阅读时间需要 4 分钟。

管道:

本质:内核的缓存

管道分类:

管道是进程间通信中最古老的方式,它是指用于连接一个读进程和一个写进程以实现他们之间通信的一个共享文件。我们将一个进程到另一个进程的数据流,称之为“管道” 。

它包括匿名管道和命名管道两种。

匿名管道:

#include
功能:创建一个无名管道 原型:int pipe (int fd[2]);参数:fd:文件描述符数组,其中fd[0]表示读端,fd[1]表示写端。返回值:成功返回0 ;失败返回错误代码。

pipe

特点:

1.只用于有亲缘关系的进程之间的通信,通常用于父子进程间的通信。         2.必须同时读写 3.管道提供流式服务4.一般而言,进程退出,管道释放,所以管道的生命周期随进程5.一般来说,内核会对管道操作进行同步和互斥 6.管道是半双工的,数据只能单向流动,需要双方通信时,需要建立两个管道

这里写图片描述

示例:从键盘读到数据,写入管道,读取管道,显示到屏幕。

代码实现:

pipepipe

运行结果:

这里写图片描述

用fork来共享管道原理

这里写图片描述

这里写图片描述

代码实现:

fork

运行结果:

这里写图片描述

示例:实现带管道的命令“ls -l | wc -l”

代码实现:

fork_pipe

运行结果:

结果

匿名管道读写规则:

  • 当没有数据可读时

    • read调用阻塞,即进程暂停执行,一直等到与数据来到为止
    • read调用返回-1,errno值为EAGAIN
  • 当管道满的时候

    • write调用阻塞,知道有进程来读数据为止
    • 调用返回-1,errno值为EAGAIN
  • 如果所有管道写端对应的文件描述符被关闭,则read返回0

  • 如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号

    SIGPIPE,进而可能导致write进程退出

  • 当要写入的数据量不大于SIG_BUF时,linux保证写入的原子性

  • 当要写入的数据量大于SIG_BUF时,linux不再保证写入的原子性

命名管道:

实现无亲缘关系进程之间的通信,用于运行于同一台机器上的任意两个进程间的通信。

如果我们想在两个不相关的进程之间交换数据,使用FIFO文件来做这项工作,它就叫做命名管道。

命名管道是一种特殊的文件。

#include 
功能:创建一个命名管道 原型:int mkfifo(const char* filename ,mode_t mode )返回值:0表示创建成功-1表示创建失败(例如:创建的目录没有权限)

匿名管道和命名管道的区别:

1.匿名管道是由pipe函数创建并打开

2.命名管道由mkfifo函数创建,打开用open

3.FIFO(命名管道)pipe(匿名管道)之间唯一的区别就是他们的创建方式和打开方式不同,但一旦这些动作完成之后,他们具有相同的语义

命名管道读写规则:

  • 如果当前打开操作是为读打开FIFO时

    • 阻塞直至有进程为写而打开该FIFO
    • 立刻返回成功
  • 如果当前打开操作是为写打开FIFO时

    • 阻塞直至有进程为读而打开该FIFO
    • 立刻返回失败,错误码为ENXIO
你可能感兴趣的文章
Flume入门
查看>>
Flume单Channel多Sink配置
查看>>
flume 的source 、channel和sink 多种组合
查看>>
从源头入手,一分钟秒懂为什么要搞微服务架构?
查看>>
TCP连接状态详解及TIME_WAIT过多的解决方法
查看>>
CPU 硬盘性能到底相差多少
查看>>
B树、B+树、B*树 总结
查看>>
kafka常用命令
查看>>
kafka顺序消息
查看>>
Kafka:Producer Config 配置
查看>>
Kafka:(Consumer配置)
查看>>
kafka 消息服务
查看>>
从零开始玩转JMX(一)——简介和Standard MBean
查看>>
究竟啥才是互联网架构中的高并发!
查看>>
数据库水平扩展与垂直扩展
查看>>
异地多活问题
查看>>
Http_load测试说明
查看>>
nginx优化——包括https、keepalive等
查看>>
记一次压力测试和对nginx/tomcat配置的调整
查看>>
第二章 HttpClient 连接管理
查看>>