读书笔记

《程序员的自我修养》之同步与锁

    为了避免多个线程同时读写同一个数据而产生不可预料的后果,我们需要将各个线程对同一个数据的访问同步。所谓同步(Synchronization),即一个线程访问数据未结束时,其他线程不得对同一个数据进行访问,它实现了数据访问的原子化。同步最常见的方法是使用锁,锁是一种非强制机制,每一个线程在访问数据或资源之前首先试图获取锁,并在访问之后释放锁。在锁已经被占用的时候试图获取锁时,线程会等待,直到锁重新可用。

[同步是一种结果,锁是为了达到同步的结果而采取的手段,信号量、互斥量、临界区等都是不同类型的锁]

    二元信号量(Binary Semaphore),是最简单的一种锁,它只有两种状态:占用/非占用,它适合只能被唯一一个线程独占访问的资源。当二元信号量处于非占用状态时,第一个试图获取该二元信号量的线程会获得锁,并将二元信号量置为占用状态,此后其他的所有试图获取该二元信号量的线程将会等待,直到该锁被释放。

    对于允许多个线程并发访问的资源,多元信号量简称信号量,他是一个很好的选择。一个初始值为N的信号量允许N个线程并发访问。线程访问资源的时候首先获取信号量,进行如下操作:

线程访问资源:信号量减1;如果信号量小于0,线程进入等待状态,否则继续执行;

线程释放资源:信号量加1;如果信号量小于1,唤醒一个等待中的线程。


     互斥量(Mutex),跟二元信号量很类似,资源仅同时允许一个线程访问,但和信号量不同的是,信号量在整个系统可以被任意线程获取并释放,也就是说,同一个信号量可以被系统中的一个线程获取之后由另一个线程释放。而互斥量则要求哪个线程获取了互斥量,哪个线程就要负责释放这个锁,其它线程越俎代庖去释放互斥量是无效的。

 

     临界区(Critical Section),是比互斥量更为严格的同步手段。在术语中,把临界区的锁的获取称为进入临界区,而把锁的释放称为离开临界区。临界区与互斥量、信号量的区别在于,互斥量和信号量在系统的任何进程里都是可见的,也就是说,一个进程创建了一个互斥量或信号量,另一个进程试图去获取该锁是合法的。然而,临界区的作用范围仅在于本进程,其他进程无法获取该锁。除此之外,临界区具有和互斥量相同的性质。

 

[互斥量与信号量不同的是,互斥量需要满足谁获取谁释放的要求;

临界区与信号量、互斥量的区别是,信号量、互斥量在系统的任何进程里都是可见的,而临界区的作用范围仅限于本进程,其他进程无法获取该锁]

 

    读写锁(Read-Write Lock),对于同一个锁,有两种获取方式:共享的(Shared),独占的(Exclusive)。当锁处于自由时,两种获取锁的方式都成功;当锁处于共享状态时,其他线程以共享的方式获取锁仍然成功;当锁处于独占状态时,其他线程必须等待其释放。

 

     条件变量(Condition Variable),可被多个线程等待(线程等待某个事件),条件变量被唤醒(事件发生),所有线程可以一起恢复执行。

你可能感兴趣的:(程序员,读书笔记)