返回顶部
首页 > 资讯 > 后端开发 > Python >Python Thread虚假唤醒概念与防范代码分析
  • 491
分享到

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

2023-07-05 06:07:26 491人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

这篇文章主要介绍“python Thread虚假唤醒概念与防范代码分析”,在日常操作中,相信很多人在Python Thread虚假唤醒概念与防范代码分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对

这篇文章主要介绍“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虚假唤醒概念与防范代码分析”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: Python Thread虚假唤醒概念与防范代码分析

本文链接: https://lsjlt.com/news/350266.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作