第十一章读书笔记
并发(concurrency)指的是多个执行单元同时、并行被执行。而并发的执行单元对共享资 源〈如硬件资摞、程序中的全局变量、静态变量等〉的访问很容易导致竞态条件( race conditions)。例如,有一个设备文件。进程 A 向该个设备文件写入 1000 个“a飞而进程 B 向 设备文件写入了 2000 个“b”,每次写数据之前会清空上一次写入的数据。现在有一个进程 C, 需要先读出进程 A 写入设备文件的全部字符( 1000 个“a”〉,然后再读出进程 B 写入设备文 件的全部字符(2000 个“b勺。如果按正常的执行顺序,应该是 A今C今B今c. 也就是说 A 进 程先向设备文件写数据,写完后, C 进程再读取数据,然后 B 进程向设备文件写入数据,最 后再由 C 进程读取数据。
原子操作就是指单位操作,也就是说, 原子操作在执行的过程中不能被中断。实际上,在 C、 C++、 Java 等语言中看似原子的语旬,本质上都不是原子的,这就需要通过某些机制使其变成原子 操作,否则在并发的环境中可能会产生脏数据〈由多进程或多线程同时访问某一共享数据而产生的 不符合预期的数据〉
并发和竞态在 Linux 内核中是普遍存在的。中断屏蔽、原子操作、自旋锁、 信号量、 互斥体都 是解决并发问题的机制。中断屏蔽很少单独使用,原子操作只能对整数和位进行操作,而自旋锁、 信号量、 互斥体的应有比较广泛。当然,如果强调代码片段的执行顺序, 可以使用完成量。 自旋锁会由于不断自旋而导致死循环(也就是死锁〉,而且锁定状态会造成 臼U 闲置,因此用 自旋锁保护的临界区的代码不能执行时间过长,当然,更不允许临界区出现阻塞情况。信号量允许 临界区阻惑,因此适用于大临界区的情况. 读写↓自旋锁和读写信号量分别是放宽了条件的自旋锁和信号量,它们允许多个执行单元同时对 .共享资源执行读操作。