通信、锁

函数通信

  • 简单通信方式:允许进程向其他进程发送简单信息

    • 命令行参数
    • 信号:受控于操作系统的非同步事件机制
    • shell环境变量
    • 程序退出状态码
    • 简单文件
  • 匿名管道:允许共享文件描述符的线程、进程传递数据

    • 仅在进程内部存在,通常和进程分支合用作为父进程、 子进程之间的通信手段、线程之间通信

    • 依赖于类Unix下进程分支模型,可移植性差

  • 具名管道FIFO:映射到系统的文件系统,允许不相关程序 进行交流

    • 是真正的外部文件,通过标准文件接口实现
    • 可以独立启动,局限于本地进程通信时可以替代套接字
    • 相较于普通外部文件,操作系统同步化FIFO访问,使之 适合IPC
  • 套接字socket:映射到系统级别端口号

    • 允许远程联网机器程序之间交流
    • 可移植性较好,几乎所有平台都支持
  • 共享内存:消息保存在函数外部,不随着函数栈清除消失

    • 全局变量
    • 类中变量

  • 线程/进程调度本质上是不确定的

  • 并行编程中错误使用锁机制可能会导致随机数据损坏、其他 异常行为,即竞争条件

  • 最好在临界区(对临界资源进行操作的部分代码)使用锁

死锁、预防

  • 线程/进程同时获取多个锁

避免、预防方案

  • 尽可能保证每个线程/进程只能同时保持一个锁

  • 为程序中每个锁分配唯一ID,然后只允许按照升序规则使用 多个锁

    • 单纯按照对象ID递增顺序加锁不会产生循环依赖,而循环 依赖时死锁必要,从而避免进入死锁状态
    • 可以数学上证明,这样能保证程序不会进入死锁状态

检测、恢复方案

  • 引入看门狗计数器:
    • 线程正常运行时每隔一段时间重置计数器
    • 没有发生死锁时正常运行
    • 一旦发生死锁,无法重置计数器导致计数器超时,程序通过 重启恢复自身状态