1. 概述
进程间通信(IPC:Inter Processes Communication) 进程是一个独立的资源分配单元,不同进程(这里所说的进程通常指的是用户进程)之间的资源是独立的,没有关联,不能在一个进程中直接访问另一个进程的资源(例如:打开的文件描述符)。
进程不是孤立的,不同的进程需要进行信息的交互和状态的传递等,因此需要进程间通信。
2. 进程间通信功能
数据传输:一个进程需要将它的数据发送给另一个进程。
资源共享:多个进程之间共享同样的资源。
通知事件:一个进程需要向另一个或一组进程发送消息,通知它们发生了某种事件。
进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有操作,并能够及时知道它的状态改变。
3. Linux操作系统支持的主要进程间通信的通信机制
3.1 进行间通信的实质
- 系统只要创建一个进程,就会给当前进程分配4G的虚拟内存(32位操作系统),虚拟内存不是常说的内存条的空间,内存条的空间称为物理内存,虚拟内存和物理内存之间存在映射关系;
- 4G的虚拟内存分为3G的用户空间(3~3G)和1G(3~4G)的内核空间,用户空间是进程所私用的,每一个进程的用户空间只能自己访问和使用,我们之前说的栈区、堆区、数据区、代码区等都得用户空间的区域;
- 内核空间是所有进程共有的,也就意味着绝大多数进程间通信方式,本质就是内核空间的操作;
3.2 特殊的进程间通信方式
- socket通信可以实现不同主机的进程间通信,其它6个只能在一台主机的多个进程间通信。
- 信号通信是唯一的一种异步通信机制。
- 共享内存是所有进程间通信方式中效率最高的,它是直接对物理内存进行操作。
4. 信号
4.1 信号概念
在Linux系统中,信号是一种用于通知进程发生某种事件或错误的机制。当某个事件发生时,内核会向相应的进程发送一个信号,进程可以通过捕获信号并根据需要进行相应的处理。
4.2 信号分类
标准信号和实时信号。标准信号范围为1-31,而实时信号范围为32-64。
4.3 信号特点
信号是软件中断,它是在软件层次上对中断机制的一种模拟。
信号可以导致一个正在运行的进程被另一个正在运行的异步进程中断,转而处理某一个突发事件。
信号是一种异步通信方式。
进程不必等待信号的到达,进程也不知道信号什么时候到达。
信号可以直接进行用户空间进程和内核空间进程的交互,内核进程可以利用它来通知用户空间进程发生了哪些系统事件。
每个信号的名字都以字符SIG开头。
每个信号和一个数字编码相对应,在头文件signum.h中,这些信号都被定义为正整数。
4.4 信号名定义路径
/usr/include/i386-linux-gnu/bits/signum.h (ubuntu12.04)
/usr/include/x86_64-linux-gnu/bits/signum.h (ubuntu16.04)
在Linux下,要想查看这些信号和编码的对应关系,可使用命令:kill l
注意:信号是由当前系统已经定义好的一些标识,每一个标识都会在特定的场合使用并且都会对进程有一定的影响,当信号产生时,会让当前信号做出相应的操作,这些信号都是已经定义好的,我们不能自己再去创造,直接使用这些就可以
4.5 产生信号的方式
-
当用户按某些终端键时,将产生信号。例如:终端上按“Ctrl+c”组合键通常产生中断信号SIGINT、终端上按"Ctrl+\"键通常产生中断信号SIGQUIT、终端上按"Ctrl+z"键通常产生中断信号SIGSTOP。
- 硬件异常将产生信号:除数为0,无效的内存访问等。这些情况通常由硬件检测到,并通知内核,然后内核产生适当的信号发送给相应的进程。
- 软件异常将产生信号:当检测到某种软件条件已发生,并将其通知有关进程时,产生信号。
- 调用kill函数将发送信号:注意:接收信号进程和发送信号进程的所有者必须相同,或发送信号进程的所有者必须是超级用户。
- 运行kill命令将发送信号:此程序实际上是使用kill函数来发送信号。也常用此命令终止一个失控的后台进程。
4.6 信号的默认(缺省)处理方式
当进程中产生了一个信号,就会让当前进程做出一定的反应,默认处理进程的方式如下
终止进程:当信号产生后,当前进程就会立即结束
缺省处理:当信号产生后,当前进程不做任何处理
停止进程:当信号产生后,使得当前进程停止
让停止的进程回复运行:当信号产生后,停止的进程会回复执行(后台进程)
注意:每一个信号只有一个默认的处理方式
4.7 进程接收到信号后的处理方式
- 执行系统默认动作:对大多数信号来说,系统默认动作是用来终止该进程。
- 忽略此信号:接收到此信号后没有任何动作。
- 执行自定义信号处理函数:用用户定义的信号处理函数处理该信号。
注意:SIGKILL和SIGSTOP这两个信号只能以默认的处理方式执行,不能忽略也不能自定义。
4.8 常见的信号
信号 |
值 |
性质 |
默认处理方式 |