操作系统(五)
上一篇我们介绍了锁的概念,通过硬件和操作系统提供的能力来实现锁。然而,锁并不是并发程序设计所需的唯一原语。 具体来说,在很多情况下,线程需要检查某一条件(condition)满足之后,才会继续运行。例如线程的 Join 函数。
条件变量
线程可以使用条件变量(condition variable)(,来等待一个条件变成真。条)变量是一个显式队列,当某些执行状态(即条件,condition)不满足时,线程可以把自己加入队列,等待(waiting)该条件。另外某个线程,当它改变了上述状态时,就可以唤醒一个或者多个等待线程(通过在该条件上发信号),让它们继续执行。
信号量
信号量是有一个整数值的对象,可以用两个函数来操作它。在 POSIX 标准中,是 sem_wait() 和 sem_post():
|
首先,sem_wait() 要么立刻返回(调用 sem_wait() 时,信号量的值大于等于 1),要么会让调用线程挂起,直到之后的一个 post 操作。当然,也可能多个调用线程都调用 sem_wait(),因此都在队列中等待被唤醒。
其次,sem_post() 并没有等待某些条件满足。它直接增加信号量的值,如果有等待线程,唤醒其中一个。
最后,当信号量的值为负数时,这个值就是等待线程的个数。
接下来我们介绍一些信号量的应用。
二值信号量(锁)
|
上例是用信号量来实现锁。因为锁只有两个状态,所以这种用法有时也叫作二值信号量(binary semaphore)。
信号量用作条件变量
信号量也可以用在一个线程暂停执行,等待某一条件成立的场景。
|
实现信号量
利用底层的同步原语(锁和条件变量),来实现一个信号量:
|