是谁,在敲打我窗?是谁,在撩动琴弦?
信号量概念及基本操作
信号量用于记录当前资源的数量,从而实现线程同步,其基本实现是一个能够原子递增和递减的整数,信号量只有两种操作,wait
和post
,其中wait
表示占据信号量资源,会将信号量-1,如果信号量为0,表示当前资源耗尽,会陷入等待;而post
表示归还对应的信号量资源,对应的伪代码如下:
1 | // wait 操作 |
二进制信号量
当信号量v的值只能取0或1时,信号量退化为一个二进制信号量,此时资源具有排他性,同一时刻只能有一个进程占据信号量并访问临界区,这时信号量有点像一个锁:
1 | wait() // 上锁 v == 0 |
但是这不意味着用二进制信号量能够代替锁,锁和二进制信号量的一个区别是:锁是谁申请,谁释放;而二进制信号量则没有该限制,所以完全有可能A线程执行wait
,B线程执行post
经典信号量问题
哲学家进餐问题
假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌上有五碗面,每位哲学家之间各有一支餐叉。因为用一支餐叉很难吃到面条,所以假设哲学家必须用两支餐叉吃东西。他们只能使用自己左右手边的那两支餐叉。而餐桌上只有五根叉子