大家好,今天我们继续Python“多线程”的学习,在文章中,我们举了大黄和小黑共用一个狗盆的例子,来解释线程同步的问题,在这个例子中,狗盆也就是共享资源只有一个,那如果遇到拥有多个共享资源的情形,怎么办呢,还能用Lock对象吗?还是举小狗吃东西的例子,不过现在狗有三只大黄、小黑、大牛,狗盆有两个。该怎么办,大家考虑考虑。
好了,不难为大家了,解决办法前人已经帮我们想好了,我们只需要学会使用即可,针对多个线程使用多个共享资源的情形,操作系统的解决办法是使用更高级的同步机制信号量代替锁,在Python3中,threading模块提供了类BoundedSemaphore实现了信号量,下面给出具体实现代码。
执行结果如下图所示:
功能完美实现了,下面我简单解释一下:
threading.BoundedSemaphore(2)用于新建一个信号量对象。参数2表示共享资源的数量,在这里2就表示有两个狗盆可供使用。
除了BoundedSemaphore类,threading模块中还提供了Semaphore类,不过不建议使用那个,因为后者是无边界的,说人话就是,可以调用release方法使得可用狗盆的数量远远超过初始化时设置的值2,这显然是不合理的。
classMythread(threading.Thread)及后续的代码,通过创建Thread类的子类,并重写子类中的run方法来生成我们所需要的线程类。thread1=Mythread(小黑,2,骨头)等代码用于创建一个Mythread类的实例,也就是创建一个线程。其他的文章中已经介绍过了,在此不重复,对了,提一个小技巧,我们可以通过分号;将多条语句写在同一行内,没什么实际作用,代码美观嘛。
OK,这部分内容差不多就到这儿了,现在我们进入到下一个情境,生产者—消费者问题,即只有生产者生产出来东西了,消费者才能消费。还是举给小狗喂食的例子,大黄,小黑,大牛在嗷嗷待哺,我手里拿着一盆肉往下扔,谁抢到就是谁的。PS:很称职的铲屎官。这个能否用Lock实现呢?请看下图。
貌似可以执行,对不,大家请看一下执行结果。
肉的数量都变成负数了,不对啊!为啥呢,因为没有一个机制判断资源的数量并阻塞线程,那怎么办呢,这时就需要Condition出马了。代码如下。
我们可以看到,Condition对象比Lock对象多了一个wait方法以及notify方法,分别用于在资源没有时阻塞线程,以及当资源可用时,唤醒wait的线程。下面是程序执行效果。
下面给出Condition类的官方文档,大家看一下
上面的英文解释比较简单,在此我就不多作解释了,OK,我们本次的内容就到这儿,大家一定要注意多多理解,线程的使用场合非常多,特别是在网络应用中尤其重要。感谢大家的