多线程编程5:线程同步和进程通信(C++11和linux)

常见的线程同步

  • linux:
    • 互斥锁:实现共享资源的串行访问,有三个版本普通锁(默认属性),检错锁(可以防止相同线程重复加锁)和递归锁(相同线程可以重复加锁)
    • 条件变量:配合互斥锁使用,实现线程之间的通信,可以唤醒一个线程,也可以唤醒全部线程,需要防止虚假唤醒
    • 信号量:可以实现线程的通信,也可以搭配mutex实现,完成对共享资源的保护,可以通过资源数控制唤醒的线程数量
    • 读写锁:比互斥锁效率更高,能够实现读操作的并行,默认属性读优先级更高
  • C++11:
    • 互斥锁:需要搭配lock_guardunique_lock使用,防止因为代码逻辑忽略解锁问题,除了普通的mutex,还有超时版本time_mutex, 递归版本recursive_mutex
    • 条件变量:需要搭配加锁了的unique_lock使用

常见进程通信(linux)

  • 信号量:
    • 设置sem_init(sem_t* sem, int pshared, unsigned int value);第二个参数为非0即可。
  • 管道:半双工单向传输
    • 在内核中开辟一块缓冲区,多个进程拿到同一个管道的句柄,就可以访问同一个缓冲区实现通信,实现单向传输,一个进程传,一个进程拿。有匿名管道和命名管道
    • 匿名管道:
      • 内核缓存区没有标识,只能用于父子进程通信,子进程会复制父进程的所有信息,包括管道句柄;
      • 通过pipe()来实现
    • 命名管道:
      • 内核缓冲区有标识符,可以用于不同进程之间的通信
      • 通过mkfifo name.fifo 创建一个命名管道
  • 消息队列
    • 内核里面的一个优先级队列,多个进程访问同一个队列,进行添加节点或者获取节点通信
  • 共享内存
    • 在物理内存中开辟了一块内存空间,多个进程将虚拟地址映射到相同的物理内存上,就可以直接通过虚拟地址访问相同的物理内存实现通信。
    • 相比管道和消息队列,减少信息的拷贝。
  • Socket套节字:将socket()函数的第一个参数改为AF_UNIX即可

你可能感兴趣的:(多线程编程,c++,linux)