通信、锁
函数通信
简单通信方式:允许进程向其他进程发送简单信息
- 命令行参数
- 信号:受控于操作系统的非同步事件机制
- shell环境变量
- 程序退出状态码
- 简单文件
匿名管道:允许共享文件描述符的线程、进程传递数据
仅在进程内部存在,通常和进程分支合用作为父进程、 子进程之间的通信手段、线程之间通信
依赖于类Unix下进程分支模型,可移植性差
具名管道FIFO:映射到系统的文件系统,允许不相关程序 进行交流
- 是真正的外部文件,通过标准文件接口实现
- 可以独立启动,局限于本地进程通信时可以替代套接字
- 相较于普通外部文件,操作系统同步化FIFO访问,使之 适合IPC
套接字socket:映射到系统级别端口号
- 允许远程联网机器程序之间交流
- 可移植性较好,几乎所有平台都支持
共享内存:消息保存在函数外部,不随着函数栈清除消失
- 全局变量
- 类中变量
锁
线程/进程调度本质上是不确定的
并行编程中错误使用锁机制可能会导致随机数据损坏、其他 异常行为,即竞争条件
最好在临界区(对临界资源进行操作的部分代码)使用锁
死锁、预防
- 线程/进程同时获取多个锁
避免、预防方案
尽可能保证每个线程/进程只能同时保持一个锁
为程序中每个锁分配唯一ID,然后只允许按照升序规则使用 多个锁
- 单纯按照对象ID递增顺序加锁不会产生循环依赖,而循环 依赖时死锁必要,从而避免进入死锁状态
- 可以数学上证明,这样能保证程序不会进入死锁状态
检测、恢复方案
- 引入看门狗计数器:
- 线程正常运行时每隔一段时间重置计数器
- 没有发生死锁时正常运行
- 一旦发生死锁,无法重置计数器导致计数器超时,程序通过 重启恢复自身状态