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入门到精通大专栏

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雷学委

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值