本文
- 主要是集中讲述进程通信和线程同步的几种方式和模型,它们分别在那些使用场景和适用条件。
- 分析进程与线程的区别(资源、创建、调度管理等)
- 各自的实现机制
进程通信和线程同步
进程通信(APUE 15/17章):注意,这里是进程间通信是指:同一台计算机的进程
使用场景
- 管道
- 匿名管道(pipe族):只能在两个相关进程使用,并且这两个相关进程有一个共同的祖先进程。
- 命名管道FIFO(mkfifo族):不相关的进程也能交换数据。
- 消息队列:消息的链接表,存储在内核,适合需要具备优先级,信息数据的格式化,具备标识符标识。
- 信号量:实际为一个计数器,适合多个进程提供对共享数据对象的访问。
- 共享内存:IPC中最快的一种,适合大数据块传输。
- Unix Socket:在同一计算机内运行的两个进程之间传送打开文件描述符。
- 信号(严格来说,不太算,但它确实也能实现进程间通信)
常用搭配
- 共享内存是一块没有互斥控制的数据交互空间,常出现:共享内存(数据传输)+信号量(同步互斥),两者搭配使用。
- 三种IPC机制:消息队列、信号量、共享内存
你可能没有看完整个IBM套装:
- Linux环境进程间通信(一)管道及有名管道,链接
- Linux环境进程间通信(二): 信号(上),链接
- Linux环境进程间通信(二): 信号(下),链接
- Linux环境进程间通信(三)消息队列,链接
- Linux环境进程间通信(四)信号灯,链接
- Linux环境进程间通信(五): 共享内存(上),链接
- Linux环境进程间通信(五): 共享内存(下),链接
- Linux 环境进程间通信(六)套接口,链接
线程同步
使用场景
- 互斥量:二值信号量,保护多个线程同时更改共享资源。
- 读写锁:适合对共享资源读的次数远大于写的情况。
- 条件变量:当需要另外某种在等待某个条件发生期间,让线程投入睡眠。
- 自旋锁:与互斥量类似,但不会将进程(线程)投入休眠而阻塞,而是在获取锁之前一直处于忙等(自旋)阻塞状态。适用于:锁被持有的时间短,而且线程并不希望在重新调度上花费太多的成本。(如果使用互斥量则有投入睡眠/唤醒,这两操作会有内核与进程间的切换,调度消耗资源)
- 屏障:用户协调多个线程并行工作的同步机制,所有的合作线程达到之后继续执行。
常用搭配
- 条件本身由互斥量保护,条件变量与互斥量一起使用,允许线程以无竞争方式等待特定的条件发生。
- 线程、互斥量、条件变量,是线程开发的三个基本概念。
你可能没有看完整个IBM套装:
- Posix线程编程指南(1) 线程创建与取消,链接
- Posix线程编程指南(2) 线程私有数据,链接
- Posix线程编程指南(3) 线程同步,链接
- Posix线程编程指南(4) 线程终止,链接
- Posix线程编程指南(5) 杂项,链接
- Linux 的多线程编程的高效开发经验,链接
进程与线程分析
并不完整和全面的,我根据开发实际需要考虑到的问题,来书写本节的内容的。
进程
- fork返回值的意义和缘由(0是内核交换进程,1是init进程,所以返回0的必然是子进程,而父进程ID是不确定的,恰好-1是错误)
- 写时复制(对于数据段、堆和栈,内核都只对子进程修改的部分制作副本,而不是父进程的全部)
- 共享正文段,使用exec族函数替换正文段
- 继承:文件描述符、已经连接的共享内存段(因为是映射,也就是浅拷贝)、信号的屏蔽和安排(信号处理函数依然有效,因为在正文段)、环境与资源限制(环境表与系统的资源设置)
线程
- 独自的线程控制块,用于系统调度
- 享有私有堆栈(线程的“执行栈”)
- 共享进程内的所有资源
实现机制
进程
这个实现机制,是操作系统的层面,不作任何评论。
线程