文章目录
Linux 进程间通信
方式包括 管道
(匿名管道
和命名管道
)、信号
、消息队列
,共享内存
、信号量
和 套接字
等方式。
序号 | 描述 |
---|---|
1 | 管道 :匿名管道 (pipe)和命名管道 (named pipe) |
2 | 信号 (Signal) |
3 | 消息队列 (Message Queue) |
4 | 共享内存 (Shared Memory) |
5 | 信号量 (Semaphore) |
6 | 套接字 (Socket) |
1、管道(pipe,named pipe)
管道
是一个进程
连接数据流
到另一个进程
的通道
,它通常被用来把一个进程的输出端
连接到另一个进程的输入端
。
在Linux命令
中通常用符号|
来表示管道
。例如:
ps -ef | grep init
此命令中ps
(process status
)是一个独立的进程
,grep
也是一个独立的进程
,中间的管道
把ps
原本要输出到屏幕
的数据
输出到grep
中,作为grep
这个进程的输入
。
管道
分为匿名管道
和命名管道
两种:
序号 | 管道 | 描述 |
---|---|---|
1 | 匿名 管道(pipe) | 主要用于两个有父子关系 的进程间通信 |
2 | 命名 管道(named pipe) | 主要用于没有父子关系 的进程间通信 |
管道:通常用于具有亲缘关系的父子进程或者兄弟进程间通信,是半双工的,数据只能往一个方向流动,先入先出,与自来水管很相似。如果需要双方互通,必须建立两个管道。 | ||
命名管道:突破了进程间的亲缘关系限制,即非父子、兄弟进程之间也可相互通信。 |
2、信号(Signal)
信号是在软件层次上 对中断机制的一种模拟,它是比较复杂的通信方式,用于通知接受进程有某事件发生。
一个进程收到一个信号 与 处理器收到一个中断请求,效果上可以说是一样的。
3、消息队列(Message Queue)
消息队列 是消息的链接表,包括 Posix 消息队列 和 System V 消息队列。
它克服了 前两种通信方式中 信息量有限
的缺点,具有 写权限的进程 可以向消息队列中 按照一定的规则添加新消息;对消息队列 有读权限 的进程可以从 消息队列中 读取消息。
4、共享内存(Shared Memory)
共享内存
是允许 两个不相关
的 进程
访问 同一个逻辑内存
的 进程间通信方法
,是在两个正在运行的 进程
之间 共享和传递数据
的一种非常有效的方式。
共享内存
可以说这是 最有用的 进程间通信方式。它使得 多个进程 可以访问 同一个内存空间,不同进程 可以及时看到 对方进程 中对 共享内存
中 数据的更新。
这种通信方式需要 依靠某种 同步机制,如 互斥锁
和 信号量
等。
两个进程使用 共享内存
的 通信机制
如图所示:
5、信号量(Semaphore)
多进程 编程
中需要关注 进程间
的 同步
(Sync) 及 互斥
(Mutex) 问题。
同步
是指多个进程 为了完成同一个任务
相互 协作运行
,而 互斥
是指不同的进程 为了争夺有限的系统资源
(硬件或软件资源)而相互 竞争运行
。
信号量
是用来解决 进程间 同步与互斥
问题的一种 进程间通信机制
。
信号量
是一个特殊的变量,变量的值代表着 关联资源的可用数量
。若等于 0
则意味着目前 没有可用的资源
。
根据 信号量的值
可以将 信号量
分为 二值信号量
和 计数信号量
:
序号 | 信号量 | 描述 |
---|---|---|
1 | 二值 信号量 | 信号量 只有0 和1 两种值。若资源被锁住,信号量值为 0 ,若资源可用则信号量值为1 |
2 | 计数 信号量 | 信号量 可在0 到一个大于1的数 (最大 32767 )之间取值。该计数 表示可用资源的个数 |
信号量
只能进行两个 原子操作
:P操作
、V操作
。
(原子操作
就是指 不能再进一步分割 的操作)
P原子操作
和 V原子操作
的具体定义如下:
序号 | 操作 | 描述 |
---|---|---|
1 | P操作 (Proberen) | (1)如果有可用的资源 (信号量值>0 ),则占用一个资源 (将信号量值减1 )。(2)如果 没有可用的资源 (信号量值=0 ),则进程 被阻塞 (block) 直到系统将资源分配 给该进程(进入 信号量 的等待队列 ,等到资源后再唤醒 该进程)。 |
2 | V操作 (Verhogen) | 如果在该信号量 的等待队列 中有进程 在等待资源 ,则唤醒 一个阻塞进程 。如果没有进程等待它,则 释放一个资源 (给信号量值加1 )。 |
6、套接字(Socket)
套接字 是一种 更为一般的 进程间通信机制,它可用于不同机器之间的进程间通信,应用非常广泛。