Linux内核同步方法——信号量

信号量

    Linux中的信号量是一种睡眠锁

    如果有一个 任务试图获得一个不可用(已经被占用)的信号量是,信号量将会将其推进一个等待队列,然后让其睡眠。这时处理器能重获自由,从而去执行其他代码。当持有的信号量可用(被释放)后,处于等待队列的哪个任务将被唤醒,并获得该信号量。

    举个门和钥匙的例子,当某个人到了门前,拿到钥匙,然后进入房间。最大的差异在于,当另一个人来到门前,但无法得到钥匙会发生什么情况。在这种情况下,这个人会把自己名字卸载一个列表中,然后打盹去了。当里边的人出房间后,首先会查看列表。如果列表上有名字,就对第一个名字仔细检查,然后叫醒那个人,让他进入房间。

在这种方式中,钥匙相当于信号量,确保一次只有一个人(执行线程)进入房间,这里的房间相当于临界区。


------------------------------------------------------------------

信号量和自旋锁在使用上的差异如下:

· 由于争用信号量的进程在等待锁重新变为可用时会睡眠,所以信号量适用于锁会被长时间持有的情况。

· 如果锁被短时间持有时,就不适合使用信号量。因为睡眠、维护等待队列以及唤醒所花费的可能会比锁被占用的全部时间还要长。

· 由于执行线程在锁被争用时会睡眠,所以只能在进程上下文中才能获取信号量锁,因为在中断上下文中是不能进行调度的

· 占用信号量的同时不能占用自旋锁。因为在你等待信号量是可能会睡眠,而在持有自旋锁时是不允许睡眠的。

· 信号量不同于自旋锁。信号量不会禁止内核抢占,所以持有信号量的代码可以被抢占。意味着信号量不会对调度的等待时间带来负面影响。

    如果需要在自旋锁和信号量中做选择,应该根据锁被持有的时间长短做判断。还有是否需要睡眠。

    信号量具有睡眠特性。而对于自旋锁,如果一个线程试图获得一个被已经持有(争用)的自旋锁,那么该线程就会一直进行忙等待——旋转——等待锁重新可用


-----------------------------------------------------------------------

计数信号量

    信号量中的计数信号量有一个特性,他可以允许任意数量的锁持有者,而自旋锁在一个时刻最多允许一个任务持有它。

    计数信号量不能进行强制互斥,因为它允许多个执行线程同时访问临界区。


互斥信号量

    在一个时刻仅允许一个锁持有者,即为计数等于1的信号量。因为它或者由一个任务持有,或者根本没有任务持有它。

    互斥信号量会强制进行互斥

    信号量在1968年由Dijkstra提出,是一种常用的锁机制。信号量支持两个原子操作P()和V(),这两个名字来自荷兰语Proberen(测试操作)和Vershogen(增加操作)。

    P操作又叫做down(),V操作是up()。

    down()操作通过对信号量计数减1来请求获得一个信号量。如果结果大于0或等于0,获得信号量锁,任务就可以进入临界区;如果结果是负数,任务就会被放入等待队列,处理器先处理执行其他任务。

     相反,当临界区中的操作完成后,up()操作用来释放信号量,该操作也称为提升,因为它会增加信号量的计数值。如果在该信号量上的等待队列不为空,那么处于队列中等待的任务在被唤醒的同时会获得该信号量。


------------------------------------------------------------------------------

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值