Python的线程17 Condition类,田径赛场上的主裁判

正式的Python专栏第54篇,同学站住,别错过这个从0开始的文章!

前面介绍了死锁,Lock,Rlock,这篇我们介绍一下Condition

Condition 是什么?

这个类跟Lock和Rlock类似,但是多了wait/notify/notify_all(Java里面对应的是notifyAll)等方法,这个搞过Java的同学就非常熟悉了。

如下图,它的acquire和release方法沿用了传入的lock对象(或者默认的Rlock对象)。

屏幕快照 2022-01-26 上午12.07.06.png

所以这两个熟悉的方法,可以参考前面分享的Lock和Rlock文章。

学委这里重点讲述wait和notify,notify_all

模拟10个运动员等候信号,准备开跑!

我们看看下面的代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/1/23 11:19 下午
# @Author : LeiXueWei
# @CSDN/Juejin/Wechat: 雷学委
# @XueWeiTag: CodingDemo
# @File : thread_condition.py
# @Project : hello
import threading
import time

condition = threading.Condition()


def wait_and_run():
    condition.acquire()
    print("%s wait for signal " % threading.current_thread().name)
    condition.wait()
    print("% run" % threading.current_thread().name)
    time.sleep(1)
    print("% completed" % threading.current_thread().name)
    condition.release()


threads = []
for i in range(1, 11):
    t = threading.Thread(name="运动员" + str(i), target=wait_and_run)
    threads.append(t)


def fire():
    condition.acquire()
    print("预备")
    condition.notify_all()
    condition.wait()
    print("3...")
    time.sleep(1)
    print("2...")
    time.sleep(1)
    print("1...")
    time.sleep(1)
    print("fire")
    condition.notify_all()



threading.Thread(name="主裁判", target=fire).start()
for t in threads:
    t.start()
for t in threads:
    t.join()

print("看热闹")

这个代码有10个运动员线程,他们都在等待一个信号,然后开始竞赛,跑起来。

我们看到线程后面有一个主裁判线程,他负责处罚fire函数。

我们看到fire函数,会执行notify_all, 唤醒所有等待的运动员。

屏幕快照 2022-01-26 上午12.13.58.png

问题来了?等半天,裁判咋不喊3/2/1啊?

你知道为什么吗?

这里展示的notify_all(下面的第二行,已经通知了所有运动员开始准备。

接着裁判程序就运行到condition.wait(), 这时候裁判线程跟其他运动员一样,都进入等待状态了。

问题来了,谁来喊裁判和所有运动员(开始跑)。

def fire():
    condition.acquire()
    condition.notify_all()
    print("预备")
    condition.wait()
    //3/2/1/ 然后再notify_all

读者可以思考一下,学委这里提示一下,wait函数还也有支持超时机制。

总结

本篇介绍的Condition类,相比Lock/Rlock更复杂。

它可以实现多个线程等待一个它条件,就像田径赛场上的主裁判一样。

如果我们打开这个类的源代码(最前面的一张截图),我们会发现其内部维护了一个Rlock(默认情况下)。

可以在创建Condition对象的时候,传入一个lock对象(可以是Lock或者Rlock)来修改。

喜欢Python的朋友,请关注学委的 Python基础专栏 or Python入门到精通大专栏

持续学习持续开发,我是雷学委!
编程很有趣,关键是把技术搞透彻讲明白。
欢迎关注微信,点赞支持收藏!

猜你喜欢

转载自blog.csdn.net/geeklevin/article/details/123079586