02.进程间的通信

[TOC]

1、管道

1.1、无名管道

(1)创建无名管道

1
2
3
4
#include <unistd.h>
int pipe(int pipefd[2]);
//参数 一个至少具有 2 个int 型数据的数组,用来存放 PIPE 的读写端描述符
//返回值 成功 0 失败 -1

(2)无名管道特征

①没有名字,因此无法使用 open( )。

②只能用于亲缘进程间(比如父子进程、兄弟进程、祖孙进程……)通信。

③半双工工作方式:读写端分开。

④写入操作不具有原子性,因此只能用于一对一的简单通信情形。

⑤不能使用 lseek( )来定位。

1.2、有名管道

(1)创建有名管道

1
2
3
4
5
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
//参数 pathname:FIFO的文件名 mode:文件权限
//返回值 成功 0 失败 -1

(2)有名管道特征

①有名字,存储于普通文件系统之中。
②任何具有相应权限的进程都可以使用 open( )来获取 FIFO 的文件描述符。
③跟普通文件一样:使用统一的 read( )/write( )来读写。
④跟普通文件不同:不能使用 lseek( )来定位,原因同 PIPE。
⑤具有写入原子性,支持多写者同时进行写操作而数据不会互相践踏。
⑥First In First Out,最先被写入 FIFO 的数据,最先被读出来。

(3)读写阻塞情况

2、信号

2.1 信号概念

信号是系统软件层次上对中断机制的一种模拟(软中断方式),是一种异步通信机制。

(1)信号的生命周期:进程信号产生、信号注册、信号响应和处理、信号注销

(2)信号响应方式

①忽略信号(SIGKILL、SIGSTOP不能忽略,不能捕捉,不会阻塞)

②捕捉信号响应函数(自定义信号处理函数,当收到信号的时候,响应自定义事件)

③执行缺省操作(Linux系统下每一种信号都有规定的默认操作)

(3)接收信号的目标进程按照如下顺序来做出反应:

A) 如果该信号被阻塞,那么将该信号挂起,不对其做任何处理,等到解除对其阻塞为止。否则进入 B。

B) 如果该信号被捕捉,那么进一步判断捕捉的类型:

  1. 如果设置了响应函数,那么执行该响应函数。

  2. 如果设置为忽略,那么直接丢弃该信号。

否则进入 C。

C) 执行该信号的缺省动作

(4)kill -l查看所有信号

2.2 信号分类

2.2.1 非实时信号(不可靠信号)

前31个

(1)非实时信号不排队,信号的响应会相互嵌套。

(2)如果目标进程没有及时响应非实时信号,那么随后到达的该信号将会被丢弃。

(3)每一个非实时信号都对应一个系统事件,当这个事件发生时,将产生这个信号。

(4)如果进程的挂起信号中含有实时和非实时信号,那么进程优先响应实时信号并且会

从大到小依此响应,而非实时信号没有固定的次序。

2.2.2 实时信号(可靠信号)

后31个

(1)实时信号的响应次序按接收顺序排队,不嵌套。

(2)即使相同的实时信号被同时发送多次,也不会被丢弃,而会依次挨个响应。

(3)实时信号没有特殊的系统事件与之对应。

2.3 信号相关API

1. 发送信号 kill

2、响应方式注册