线程同步总结
锁:
锁就是线程同步中最常见的一种方式,每个线程在访问数据之前都会先获取锁,在操作结束后要释放锁。值得一提的是,锁的保护并不是强制的,需要线程自愿遵守。
信号量(semaphore):
信号量分为二元信号量和多元信号量,二元信号量就是只有两种状态的信号量,在后文中会介绍其与互斥量(Mutex)的区别。多元信号量即存在多种状态,可以用来管理多个系统资源。
信号量操作如下:
获取信号量:
1、将信号量减1
2、如果信号量<0,则进入等待状态,否则继续执行。
释放信号量:
1、将信号量加1
2、如果信号量<1,则唤醒其中一个等待的线程。
互斥量(mutex):
互斥量和二元信号量很相似,也只有两种状态。但是与二元信号量不同的是,二元信号量可以由某个线程获取,再由另一个线程释放,也就是说,信号量的获取和释放不必由同一个线程进行;而互斥量的获取和释放只能由同一个线程进行。
临界区:
临界区通常是指某一个包含访问临界区变量的代码段,获取临界区的锁称为进入临界区,释放临界区的锁称为离开临界区。值得注意的一点是,临界区只对本进程可见,区别于互斥量与信号量,互斥量与信号量是对其他进程可见的。
读写锁:
读写锁有三种状态:自由、共享(Shared)、独占(Exclusive)。读写锁可以用两种方式获取,一个是以共享的方式获取,另一个是以独占的方式获取。共享的方式可以允许多个线程同时获取,而独享的方式只能允许一个线程获取。详见下表:
读写锁的状态 | 以共享的方式获取 | 以独占的方式获取 |
---|---|---|
自由 | 成功 | 成功 |
共享 | 成功 | 等待 |
独占 | 等待 | 等待 |
有了读写锁之后,就可以实现允许多个线程读,但只允许一个线程写的操作了。
条件变量:
线程可以等待一个条件变量,当条件变量满足某一个条件时,线程会被唤醒。可以有多个线程等待一个条件变量,当这个条件变量改变时,所有线程都会被唤醒。