4、Event() 事件锁
基本介绍
事件锁是基于条件锁来做的,它与条件锁的区别在于一次只能放行全部,不能放行任意个数量的子线程继续运行。
我们可以将事件锁看为红绿灯,当红灯时所有子线程都暂停运行,并进入“等待”状态,当绿灯时所有子线程都恢复“运行”。
下面是threading模块与事件锁提供的相关方法:图一
使用方式
事件锁不能利用with语句来进行使用,只能按照常规方式。
如下所示,我们来模拟线程和红绿灯的操作,红灯停,绿灯行:图二
5、Semaphore() 信号量锁
基本介绍
信号量锁也是根据条件锁来做的,它与条件锁和事件锁的区别如下:
条件锁:一次可以放行任意个处于“等待”状态的线程
事件锁:一次可以放行全部的处于“等待”状态的线程
信号量锁:通过规定,成批的放行特定个处于“上锁”状态的线程
下面是threading模块与信号量锁提供的相关方法:图三
使用方式
以下是使用示例,你可以将它当做一段限宽的路段,每次只能放行相同数量的线程:图四
with语句
由于threading.Semaphore()对象中实现了enter__()与__exit()方法,故我们可以使用with语句进行上下文管理形式的加锁解锁操作:图五
锁关系浅析
上面5种锁可以说都是基于同步锁来做的,这些你都可以从源码中找到答案。
首先来看RLock递归锁,递归锁的实现非常简单,它的内部会维护着一个计数器,当计数器不为0的时候该线程不能被I/O操作和时间轮询机制切换。但是当计数器为0的时候便不会如此了:图六
而Condition条件锁的内部其实是有两把锁的,一把底层锁(同步锁)一把高级锁(递归锁)。
低层锁的解锁方式有两种,使用wait()方法会暂时解开底层锁同时加上一把高级锁,只有当接收到别的线程里的notfiy()后才会解开高级锁和重新上锁低层锁,也就是说条件锁底层是根据同步锁和递归锁的不断切换来进行实现的:图七
Event事件锁内部是基于条件锁来做的:图八
Semaphore信号量锁内部也是基于条件锁来做的:图九