图解Linux进程间通信实现原理(1)
为Linux应用程序的开发人员,对Linux的进程间通信方式肯定是了如指掌,平时的开发中应该会大量的使用到。当你迅速的在键盘上按下【CTRL+C】终止掉一个正在运行中的命令时,你有没有仔细的思考过背后的原理呢?或者是他们是通过什么通信方式呢?这个通信方式是怎样实现的呢?本文就带着大家去Linux进程间通信一探究竟,找出他们的原理。
概念
我们都知道,应用程序在运行起来之后(进程),是相互独立的,都有自己的进程地址空间。但是往往在一些业务上需要进程间的通信,来完成系统的某个完整的功能。我们来看下进程间通信能干那些事情?首先当然最重要的是:
- 数据传输。一个进程需要发送数据到另一个进程,这种需求肯定是存在的。
- 共享数据。如果有多个进程想要访问数据,一个进程修改了内容,另一个进程能够立即看到内容变化。
- 资源保护:上面的的操作中存在竞争情况,内核需要提供锁和同步机制。
- 通知:一个进程需要向另一个进程发送消息,通知发生了某个事件。
- 控制:有些进程需要控制另一个进程的运行。典型的例子就是gdb,可参考之前文章【gdb到底是怎么实现的?】
通信方式
进程间的通信方式一般可以分为八种,如下:
八种通信方式
他们在不同的标准都有不同的实现,如下图所示:
通信方式框图
我们先从管道开始讲起来吧。
管道
这里说的管理特指的是无名管道,它是一种半双工的通信方式。也就是说数据只能单向流动,一般是在具有亲缘关系的进程间使用,比如父子进程。当一个进程创建了一个管道,并调用fork创建自己的一个子进程后,父进程关闭读管道端,子进程关闭写管道端,这样提供了两个进程之间数据流动的一种方式。
管道是怎么通信的呢?
首先管道是内核的一个缓冲区,而且是在内存中。管道一头连接着一个进程的输出,另一头连接着另一个进程的输入。一个缓冲区不需要很大,它被设计成为环形的数据结构,以便管道可以被循环利用。当管道中没有信息的话,从管道中读取的进程会等待,直到另一端的进程放入信息。当管道被放满信息的时候,尝试放入信息的进程会等待,直到另一端的进程取出信息。当两个进程都终结的时候,管道也自动消失。看下图:
那管道怎样建立的呢?
从原理上,管道利用fork机制建立,从而让两个进程可以连接到同一个PIPE上。最开始的时候,上面的两个箭头都连接在同一个进程1上(连接在进程1上的两个箭头),如下图。当fork复制进程的时候,会将这两个连接也复制到新的进程(进程2)。随后,每个进程关闭自己不需要的一个连接 (两个黑色的箭头被关闭; 进程1关闭从PIPE来的输入连接,进程2关闭输出到PIPE的连接),这样,剩下的红色连接就构成了如上图的PIPE。
管道在内核中具体怎么实现的呢?
在Linux内核中,并没有针对管道新增数据结构。而是巧妙的借用了文件系统的file结构和虚拟文件系统的索引节点inode。通过将两个 file 结构指向同一个临时的 VFS 索引节点,而这个 VFS 索引节点又指向一个物理页面而实现的。
具体实现
管道的实现其实也不难,源代码在内核工程中的fs/pipe.c,我们着重的讲两个比较重要的接口吧,也就是常用的pipe_read()和pipe_write(),前者是管道读函数,后者是管道写函数。
管道写函数将字节数据复制到虚拟文件系统索引节点指向的物理内存页,而读函数则是相反:读出数据。当然这里存在着竞争的管理,需要一定的同步机制,使用锁,等待队列和信号。
当我们写的时候,调用write(),内核根据传入的文件描述符fd,找到该文件的file结构。然后执行结构中f_op中的写函数。写函数在向内存写入数据之前,必须首先检查虚拟文件系统索引节点信息,检查是否有足够的内存空间可以写和内存没有被读程序锁定这两个条件,只有满足了,才真正的进行内存拷贝。
接下来写函数就会锁定内存,然后复制数据到内存,否则就在虚拟文件系统inode的等待队列中。
管道的读取过程和写入过程类似。但是,进程可以在没有数据或内存被锁定时立即返回错误信息,而不是阻塞该进程,这依赖于文件或管道的打开模式。反之,进程可以休眠在索引节点的等待队列中等待写入进程写入数据。当所有的进程完成了管道操作之后,管道的索引节点被丢弃,而共享数据页也被释放。
总结
由于篇幅的限制,八大进程间通信只讲了管道,文章开头的疑问也只能等到后续文章了,也算是留个悬念吧。
图解Linux进程间通信实现原理(1)的更多相关文章
- Linux进程间通信(五):信号量 semget()、semop()、semctl()
这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信 -- 信号.下面 ...
- Linux进程间通信——使用信号量
这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信——使用信号.下面 ...
- c/c++ linux 进程间通信系列5,使用信号量
linux 进程间通信系列5,使用信号量 信号量的工作原理: 由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的: P(sv):如果sv的值大于零,就给它减1:如果 ...
- Linux进程间通信--使用信号量【转】
本文转载自:http://blog.csdn.net/ljianhui/article/details/10243617 这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号 ...
- Linux进程间通信——使用信号量(转)
这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的更多内容,可以阅读我的另一篇文章:Linux进程间通信——使用信号.下面 ...
- Linux进程间通信—管道
Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的.而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间 ...
- Linux进程间通信——使用信号量【转】
本文转载自:http://blog.csdn.net/ljianhui/article/details/10243617 这篇文章将讲述别一种进程间通信的机制——信号量.注意请不要把它与之前所说的信号 ...
- [转载]Linux Bond的原理及其不足
本文转自http://www.yunweipai.com/archives/1969.html 支持原创.尊重原创,分享知识! 在企业及电信Linux服务器环境上,网络配置都会使用Bonding技术做 ...
- Linux进程间通信(一): 信号 signal()、sigaction()
一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...
随机推荐
- 编程模型&编程思想
编程模型 1.面向对象编程OOP 2.面向切面编程AOP Java静态接口,Java动态代理,字节码提升. 面向切面的两个方面: 拦截判断:方法,注解,参数,异常 拦截执行:前置,后置,返回,异常 3 ...
- Kafka 快速入门
Kafka Kafka 核心概念 什么是 Kafka Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写.该项目的目标是为处理实时数据提供一个统一.高吞吐.低延迟 ...
- flex 布局方式
开始啦 1. flex-direction 有关主轴的对齐方式 column 自上到下 row 自左到右 -->默认值 row-reverse 自右到左 column-reverse 自下到上 ...
- string+DP leetcode-4.最长回文子串
5. Longest Palindromic Substring 题面 Given a string s, find the longest palindromic substring in s. Y ...
- nginx的so_keepalive和timeout相关小计
KeepAlive 这里的keepalive是TCP的探活机制: [root@ ~]# sysctl -a |grep tcp_keepalive net.ipv4.tcp_keepalive_tim ...
- TreeMap源码实现类中文全解析
/** * 基于红黑树(Red-Black tree)的 NavigableMap 实现.该映射根据其键的自然顺序进行排序, * 或者根据创建映射时提供的Comparator 进行排序,具体取决于使用 ...
- 理解JVM之垃圾回收
1.垃圾收集算法 1) 标记-清楚算法:该算法是最基础的收集算法,其分为标记与清除两个阶段.首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,该算法主要有两个不足:一个是效率问题,标 ...
- 数据库 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\test1.mdf' 已存在。请选择其他数据库
关于asp.net编译中出现 数据库 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\test1.md ...
- docker alpine wkhtmltopdf
截止2019.08 wkhtmltopdf 还没有 alpine 的版本 如需使用 需要在 alpine 环境中编译 生成 wkhtmltopdf (使用 apk add wkhtmltopdf ...
- ES extended_stats 函数
在进行ES聚合分析的时候,发现了一个非常有用的函数,extended_stats,可以对聚合的结果进行更近一步的分析 ,常见的 count sum avg min max 等都可以一目了然 GET ...