锁是线程同步时的一个重要的工具,然而操作系统中包含了多种不同的锁,各种锁之间有什么不同呢?
1、信号量(Semaphore)
信号量分为二元信号量和多元信号量,所谓二元信号量就是指该信号量只有两个状态,要么被占用,要么空闲;而多元信号量则允许同时被N个线程占有,超出N个外的占用请求将被阻塞。信号量是“系统级别”的,即同一个信号量可以被不同的进程访问。
2、互斥量 (Mutex)
和二元信号量类似, 唯一不同的是,互斥量的获取和释放必须是在同一个线程中进行的。如果一个线程去释放一个并不是它所占有的互斥量是无效的。而信号量是可以由其它线程进行释放的。
3、临界区(Critical Section)
术语中,把临界区的锁的获取称为进入临界区,而把锁的释放称为离开临界区。临界区是“进程级别”的,即它只在本进程的所有线程中可见,其它性质与互斥量相同(即谁获取,谁释放)
4、读写锁(Read-Write Lock)
适 用于一个特定的场合。比如对于一段线程间访问的数据,如果程序大部分时间都是在读取,而只有很少的时间才会写入,那么使用前面几种锁时,每次读取也是同样 要申请锁的,而这时其它的线程就无法再对此段数据进行读取。可是,多个线程同时对一段数据进行读取时,是不存在同步问题的,那么这些读取时设置的锁就影响 了程序的性能。读写锁的出现就是为了解决这个问题的。
对于一个读写锁,有两种获取方式:共享(Shared)或独占 (Exclusive)。如果当前读写锁处于空闲状态,那么当多个线程同时以共享方式访问该读写锁时,都可以成功;而此时如果一个线程以独占的方式访问该 读写锁,那么它会等待所有共享访问都结束后才可以成功。在读写锁被独占访问的过程中,再次共享和独占请求访问该锁,都会进行等待状态。
5、条件变量(Condition Variable)
条件变量相当于一种通知机制。多个线程可以设置等待该条件变量,而一旦另外的线程设置了该条件变量(相当于唤醒条件变量)后,多个等待的线程就可以继续执行了。