文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python Thread虚假唤醒概念与防范代码分析

2023-07-05 06:59

关注

这篇文章主要介绍“Python Thread虚假唤醒概念与防范代码分析”,在日常操作中,相信很多人在Python Thread虚假唤醒概念与防范代码分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python Thread虚假唤醒概念与防范代码分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

什么是虚假唤醒

虚假唤醒是一种现象,它只会出现在多线程环境中,指的是在多线程环境下,多个线程等待在同一个条件上,等到条件满足时,所有等待的线程都被唤醒,但由于多个线程执行的顺序不同,后面竞争到锁的线程在获得时间片时条件已经不再满足,线程应该继续睡眠但是却继续往下运行的一种现象。

上面是比较书面化的定义,我们用人能听懂的话来介绍一下虚假唤醒。

多线程环境的编程中,我们经常遇到让多个线程等待在一个条件上,等到这个条件成立的时候我们再去唤醒这些线程,让它们接着往下执行代码的场景。假如某一时刻条件成立,所有的线程都被唤醒了,然后去竞争锁,因为同一时刻只会有一个线程能拿到锁,其他的线程都会阻塞到锁上无法往下执行,等到成功争抢到锁的线程消费完条件,释放了锁,后面的线程继续运行,拿到锁时这个条件很可能已经不满足了,这个时候线程应该继续在这个条件上阻塞下去,而不应该继续执行,如果继续执行了,就说发生了虚假唤醒。

import threadingfrom threading import Conditionclass Data:    def __init__(self, cond, num):        self.num = num        self.cond = cond    def add(self):        self.cond: Condition = self.cond        self.cond.acquire()        if self.num > 0:            self.cond.wait()        self.num += 1        print(threading.current_thread().getName(), self.num)        self.cond.notifyAll()        self.cond.release()    def decr(self):        self.cond: Condition = self.cond        self.cond.acquire()        if self.num == 0:            self.cond.wait()        self.num -= 1        print(threading.current_thread().getName(), self.num)        self.cond.notifyAll()        self.cond.release()if __name__ == '__main__':    cond = Condition()    num = 0    data = Data(cond, 0)    thread_add = threading.Thread(name="A", target=data.add)    thread_decr = threading.Thread(name="B", target=data.decr)    thread_add.start()    thread_decr.start()

Python Thread虚假唤醒概念与防范代码分析

现在改用4个线程

import threadingfrom threading import Conditionclass Data:    def __init__(self, cond, num):        self.num = num        self.cond = cond    def add(self):        self.cond: Condition = self.cond        self.cond.acquire()        if self.num > 0:            self.cond.wait()        self.num += 1        print(threading.current_thread().getName(), self.num)        self.cond.notifyAll()        self.cond.release()    def decr(self):        self.cond: Condition = self.cond        self.cond.acquire()        if self.num == 0:            self.cond.wait()        self.num -= 1        print(threading.current_thread().getName(), self.num)        self.cond.notifyAll()        self.cond.release()if __name__ == '__main__':    cond = Condition()    num = 0    data = Data(cond, 0)    thread_add = threading.Thread(name="A", target=data.add)    thread_decr = threading.Thread(name="B", target=data.decr)    thread_add2 = threading.Thread(name="C", target=data.add)    thread_decr2 = threading.Thread(name="D", target=data.decr)    thread_add.start()    thread_decr.start()    thread_add2.start()    thread_decr2.start()

Python Thread虚假唤醒概念与防范代码分析

还没有出现问题!!!

使用20个线程同时跑

import threadingfrom threading import Conditionclass Data:    def __init__(self, cond, num):        self.num = num        self.cond = cond    def add(self):        self.cond: Condition = self.cond        self.cond.acquire()        if self.num > 0:            self.cond.wait()        self.num += 1        print(threading.current_thread().getName(), self.num)        self.cond.notifyAll()        self.cond.release()    def decr(self):        self.cond: Condition = self.cond        self.cond.acquire()        if self.num == 0:            self.cond.wait()        self.num -= 1        print(threading.current_thread().getName(), self.num)        self.cond.notifyAll()        self.cond.release()if __name__ == '__main__':    cond = Condition()    num = 0    data = Data(cond, 0)    for i in range(10):        thread_add = threading.Thread(name="A", target=data.add)        thread_add.start()    for i in range(10):        thread_decr = threading.Thread(name="B", target=data.decr)        thread_decr.start()

Python Thread虚假唤醒概念与防范代码分析

这时就出现了问题!!!

现在改用while进行判断

防止虚假唤醒:

import threadingfrom threading import Conditionclass Data:    def __init__(self, cond, num):        self.num = num        self.cond = cond    def add(self):        self.cond: Condition = self.cond        self.cond.acquire()        # 这里采用了while进行判断,防止虚假唤醒        while self.num > 0:            self.cond.wait()        self.num += 1        print(threading.current_thread().getName(), self.num)        self.cond.notifyAll()        self.cond.release()    def decr(self):        self.cond: Condition = self.cond        self.cond.acquire()        # 这里采用了while进行判断,防止虚假唤醒        while self.num == 0:            self.cond.wait()        self.num -= 1        print(threading.current_thread().getName(), self.num)        self.cond.notifyAll()        self.cond.release()if __name__ == '__main__':    cond = Condition()    num = 0    data = Data(cond, 0)    for i in range(10):        thread_add = threading.Thread(name="A", target=data.add)        thread_add.start()    for i in range(10):        thread_decr = threading.Thread(name="B", target=data.decr)        thread_decr.start()

Python Thread虚假唤醒概念与防范代码分析

这个例子与上面的代码几乎没有差别,只是把if判断换成了while判断,所以每次萧炎和唐三醒过来之后都会再判断一下有没有苹果(唤醒自己的条件是否满足),如果不满足,就会继续睡下去,不会接着往下运行,从而避免了虚假唤醒。

到此,关于“Python Thread虚假唤醒概念与防范代码分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯