<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
虛假喚醒是一種現象,它只會出現在多執行緒環境中,指的是在多執行緒環境下,多個執行緒等待在同一個條件上,等到條件滿足時,所有等待的執行緒都被喚醒,但由於多個執行緒執行的順序不同,後面競爭到鎖的執行緒在獲得時間片時條件已經不再滿足,執行緒應該繼續睡眠但是卻繼續往下執行的一種現象。
上面是比較書面化的定義,我們用人能聽懂的話來介紹一下虛假喚醒。
多執行緒環境的程式設計中,我們經常遇到讓多個執行緒等待在一個條件上,等到這個條件成立的時候我們再去喚醒這些執行緒,讓它們接著往下執行程式碼的場景。假如某一時刻條件成立,所有的執行緒都被喚醒了,然後去競爭鎖,因為同一時刻只會有一個執行緒能拿到鎖,其他的執行緒都會阻塞到鎖上無法往下執行,等到成功爭搶到鎖的執行緒消費完條件,釋放了鎖,後面的執行緒繼續執行,拿到鎖時這個條件很可能已經不滿足了,這個時候執行緒應該繼續在這個條件上阻塞下去,而不應該繼續執行,如果繼續執行了,就說發生了虛假喚醒。
import threading from threading import Condition class 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()
import threading from threading import Condition class 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()
還沒有出現問題!!!
import threading from threading import Condition class 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()
這時就出現了問題!!!
防止虛假喚醒:
import threading from threading import Condition class 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()
這個例子與上面的程式碼幾乎沒有差別,只是把if判斷換成了while判斷,所以每次蕭炎和唐三醒過來之後都會再判斷一下有沒有蘋果(喚醒自己的條件是否滿足),如果不滿足,就會繼續睡下去,不會接著往下執行,從而避免了虛假喚醒。
等待在一個條件上的執行緒被全部喚醒後會去競爭鎖,所以這些執行緒會一個一個地去消費這個條件,等到後面的執行緒去消費這個條件時,條件可能已經不滿足了,所以每個被喚醒的執行緒都需要再檢查一次條件是否滿足。如果不滿足,應該繼續睡下去;只有滿足了才能往下執行。
到此這篇關於Python Thread虛假喚醒概念與防範詳解的文章就介紹到這了,更多相關Python Thread虛假喚醒內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45