8.7 进程间的通讯:管道、消息队列、共享内存、信号量、信号、Socket
进程间的通讯
进程间为什么需要通讯?
共享数据、数据传输、消息通知、进程控制
进程间的通讯有哪些类型?
首先,联系前面讲过的知识,进程之间的用户地址空间是相互独立的,不能进行互相访问,但是,内核空间却是共享的,所以进程间的通信要通过内核。

这里以Linux为例,介绍几种常见的Linux进程间的通讯方式:共享内存、管道、消息队列、信号量、信号。
管道
如果你学习过linux命令肯定见过 | 这个竖线。
$ ps auxf | grep mysql
上面命令里的竖线 | 就是一个管道,它在这里的作用是:把前一个命令(ps auxf)的输出,作为后一个命令(grep mysql)的输入。
由此可见,管道传输数据是单向的。如果想互相通信,我们最少需要两个管道。
上面这例子的管道是没有名字的,所以我们称 | 这样的管道为匿名管道,用完即毁。
还有一种管道是命名管道,也叫做FIFO,先进先出的意思。
在使用命名管道前,需要通过mkfifo命令创建,还要加上管道的名字。
$ mkfifo myPipe
管道名字就是myPipe,在Linux中也是以文件的形式存在的:
w-rw-r--. 1 iron2222 iron2222 0 Dec 4 22:20 myPipe
我们尝试向这个管道里写入数据:
$ echo "hello" > myPipe //把数据写进去
//你会发现停住了,没反应
因为只有管道之中的数据被读完后,命令才可以正常退出:
$ cat < myPipe
hello
注意,一定要在另一个终端上,输入该命令,保持原终端界面保持不变,这样执行该命令后会很明显的看到,原终端命令可以正常退出了。

从这里可以看出来,管道这种方式:效率低,不适合频繁的交换数据。
消息队列
消息队列的通讯模式:A进程给B进程发消息,A进程把消息放到对应的消息队列之后就可以直接返回了,B进程需要的时候去读就可以了。
消息队列的本质是,保存在内核中的消息链表。发送方与接收方要约定好,消息体的数据类型与大小。读完之后,内核就会把这个消息体删除。

不好的地方:消息队列在通讯的过程中,存在用户态与内核态之间的数据拷贝开销。
共享内存
共享内存的机制,就是拿出来一块虚拟地址空间,映射到相同的物理内存中。读取效率很高。

缺点是,如果两个进程同时向一块物理地址中写数据时,会造成覆盖。
信号量
为了防止出现共享内存那样,出现多进程竞争共享资源,所以需要保护机制,让共享的资源,在任意时刻只能被一个进程访问。
信号量其实就是一个整型计数器,主要用于实现进咸亨间的互斥和同步,而不是用于缓存进程间通信的数据。
初始为1,有A进程去用就变成0,若此时有B进程想用,就变-1,使B进程阻塞。

就相当于一种标记,告诉进程这个共享资源有没有空。
信号
信号,一般用于那些处于异常情况下的进程间的通信,是一种异步信号,就是一个数字。
比如,在Linux中,为了相应不同的事件,提供了几十种信号,反别代表不同的意义:
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
举一个大家常见的例子:
在shell终端里,我们可以使用某些快捷键,给进程发信号:
- Ctrl+C 会产生SIGINT信号,终止进程;
- Ctrl+Z 会产生SIGTSTP信号,表示停止进程,但进程未结束。
也可以通过kill命令,但前提要知道进程的PID号。
- kill -9 1050,表示给PID为1050的进程发送9) SIGKILL信号,立即结束该进程。
唯一的异步通信机制,进程需要为信号设置相应的监听处理,执行相关操作。
Socket
如果你想跨网络与不同主机上的进程进行通讯,就要用到Socket了。
各个通讯方式总结对比

8.7 进程间的通讯:管道、消息队列、共享内存、信号量、信号、Socket的更多相关文章
- 管道 && 消息队列 && 共享内存
http://blog.csdn.net/piaoairy219/article/details/17333691 1. 管道 管道的优点是不需要加锁. 缺点是默认缓冲区太小,只有4K. 一个管道只适 ...
- .Net下的进程间的通讯 -- Windows消息队列
Windows 消息队列(MSMQ),是微软Windows2000以上的操作系统的一个服务,可以提供在计算机间消息的可靠传输,用来在两个进程间进行异步通讯最合适不过了.在.Net中有一个Message ...
- 【windows 操作系统】进程间通信(IPC)简述|无名管道和命名管道 消息队列、信号量、共享存储、Socket、Streams等
一.进程间通信简述 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进 ...
- 【转】C++ 进程间的通讯(一):简单的有名管道实现
原文: C++ 进程间的通讯(一):简单的有名管道实现 -------------------------------------------------- 进程间的通讯(一):简单的有名管道实现 ...
- 进程间的通讯(IPC)方式
内存映射 为什么要进行进程间的通讯(IPC (Inter-process communication)) 数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间共享数据 ...
- [转]WINDOW进程间数据通讯以及共享内存
1.引言 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.WIN32 API提供了许多函数使我们能够方便高效地进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换,就如同 ...
- 进程间通信机制(管道、信号、共享内存/信号量/消息队列)、线程间通信机制(互斥锁、条件变量、posix匿名信号量)
注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...
- Windows进程间通讯(IPC)----共享内存
Windows中同一个EXE文件多次加载过程 Windows中EXE文件加载是基于内存映射文件的. 当EXE文件第一次被加载. 首先系统会先创建一个进程内核对象,并创建一个新的进程地址空间. 系统调用 ...
- Linux进程通信之System V消息队列
System V消息队列是Open Group定义的XSI,不属于POSIX标准.System V IPC的历史相对很早,在上个世70年代后期有贝尔实验室的分支机构开发,80年代加入System V的 ...
随机推荐
- STM32必学的时钟系统
STM32的时钟系统 相较于51单片机,stm32的时钟系统可以说是非常复杂了,我们现在看下面的一张图: 上图说明了时钟的走向,是从左至右的从时钟源一步步的分配给外设时钟.需要注意的是,上图左侧一 ...
- 【做题记录】CF1444A Division
CF1444A Division 题意: 给定 \(t\) 组询问,每组给两个数 \(p_i\) 和 \(q_i\) ,找出最大的整数 \(x_i\) ,要求 \(p_i\) 可被 \(x_i\) 整 ...
- Java并发:AbstractQueuedSynchronizer(AQS)
队列同步器 AbstractQueuedSynchronizer 是一个公共抽象类.提供一个同步器框架,用于实现依赖于先进先出(FIFO)等待队列的阻塞锁和相关同步器(信号量,事件等).使用一个 in ...
- 像素反转 牛客网 程序员面试金典 C++ Python
像素反转 牛客网 程序员面试金典 题目描述 有一副由NxN矩阵表示的图像,这里每个像素用一个int表示,请编写一个算法,在不占用额外内存空间的情况下(即不使用缓存矩阵),将图像顺时针旋转90度. 给定 ...
- 最后的OI(HAOI2020游记)
马上就省选了,怎么不得写点什么?要不然到最后或许就真的落得个白茫茫大地真干净的局面. 其实也不知道该说啥?我这一路走来,感觉挺赚的. 每一个OIer背后都有一个故事,所以,我有故事,你有酒吗? 依稀记 ...
- Java中Lambda表达式的进化之路
Lambda表达式的进化之路 为什么要使用Lambda表达式 可以简洁代码,提高代码的可读性 可以避免匿名内部类定义过多导致逻辑紊乱 在原先实现接口抽象方法的时候,需要通过定义一个实现接口的外部类来实 ...
- 如何选择普通索引和唯一索引《死磕MySQL系列 五》
系列文章 一.原来一条select语句在MySQL是这样执行的<死磕MySQL系列 一> 二.一生挚友redo log.binlog<死磕MySQL系列 二> 三.MySQL强 ...
- git与pycharm的使用详解(git+gitlab+pycham)
前言 当自动化框架搭建出来后,需要多个人来使用框架,写自动化用例. 在这个阶段,我们不可能将写好的代码打包发给其他人,这样很麻烦,多人协作一点也不灵活. 这时候,就提现出了git的价值 一.下载安装 ...
- SpringMVC配置版到注解版
什么是springmvc? 1.1.什么是MVC MVC是模型(Model).视图(View).控制器(Controller)的简写,是一种软件设计规范. 是将业务逻辑.数据.显示分离的方法来组织代码 ...
- offsetX各种值总结
pageX: 页面X坐标位置 pageY: 页面Y坐标位置 screenX: 屏幕X坐标位置 screenY: 屏幕Y坐标位置 clientX: 鼠标的坐标到页面左侧的距离 clientY: 鼠标的坐 ...