Python線程協(xié)作threading.Condition實(shí)現(xiàn)過(guò)程解析
領(lǐng)會(huì)下面這個(gè)示例吧,其實(shí)跟java中wait/nofity是一樣一樣的道理
import threading # 條件變量,用于復(fù)雜的線程間同步鎖 """ 需求: 男:小姐姐,你好呀! 女:哼,想泡老娘不成? 男:對(duì)呀,想泡你 女:滾蛋,門(mén)都沒(méi)有! 男:切,長(zhǎng)這么丑, 還這么吊... 女:關(guān)你鳥(niǎo)事! """ class Boy(threading.Thread): def __init__(self, name, condition): super().__init__(name=name) self.condition = condition def run(self): with self.condition: print("{}:小姐姐,你好呀!".format(self.name)) self.condition.wait() self.condition.notify() print("{}:對(duì)呀,想泡你".format(self.name)) self.condition.wait() self.condition.notify() print("{}:切,長(zhǎng)這么丑, 還這么吊...".format(self.name)) self.condition.wait() self.condition.notify() class Girl(threading.Thread): def __init__(self, name, condition): super().__init__(name=name) self.condition = condition def run(self): with self.condition: print("{}:哼,想泡老娘不成?".format(self.name)) self.condition.notify() self.condition.wait() print("{}:滾蛋,門(mén)都沒(méi)有!".format(self.name)) self.condition.notify() self.condition.wait() print("{}:關(guān)你鳥(niǎo)事!".format(self.name)) self.condition.notify() self.condition.wait() if __name__ == '__main__': condition = threading.Condition() boy_thread = Boy('男', condition) girl_thread = Girl('女', condition) boy_thread.start() girl_thread.start()
Condition的底層實(shí)現(xiàn)了__enter__和 __exit__協(xié)議.所以可以使用with上下文管理器
由Condition的__init__方法可知,它的底層也是維護(hù)了一個(gè)RLock鎖
def __enter__(self): return self._lock.__enter__()
def __exit__(self, *args): return self._lock.__exit__(*args)
def __exit__(self, t, v, tb): self.release()
def release(self): """Release a lock, decrementing the recursion level. If after the decrement it is zero, reset the lock to unlocked (not owned by any thread), and if any other threads are blocked waiting for the lock to become unlocked, allow exactly one of them to proceed. If after the decrement the recursion level is still nonzero, the lock remains locked and owned by the calling thread. Only call this method when the calling thread owns the lock. A RuntimeError is raised if this method is called when the lock is unlocked. There is no return value. """ if self._owner != get_ident(): raise RuntimeError("cannot release un-acquired lock") self._count = count = self._count - 1 if not count: self._owner = None self._block.release()
至于wait/notify是如何操作的,還是有點(diǎn)懵.....
wait()方法源碼中這樣三行代碼
waiter = _allocate_lock() #從底層獲取了一把鎖,并非Lock鎖
waiter.acquire()
self._waiters.append(waiter) # 然后將這個(gè)鎖加入到_waiters(deque)中
saved_state = self._release_save() # 這是釋放_(tái)_enter__時(shí)的那把鎖???
notify()方法源碼
all_waiters = self._waiters waiters_to_notify = _deque(_islice(all_waiters, n))# 從_waiters中取出n個(gè) if not waiters_to_notify: # 如果是None,結(jié)束 return for waiter in waiters_to_notify: # 循環(huán)release waiter.release() try: all_waiters.remove(waiter) #從_waiters中移除 except ValueError: pass
大體意思: wait先從底層創(chuàng)建鎖,acquire, 放到一個(gè)deque中,然后釋放掉with鎖, notify時(shí),從deque取拿出鎖,release
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Python中多線程thread與threading的實(shí)現(xiàn)方法
- python基于queue和threading實(shí)現(xiàn)多線程下載實(shí)例
- Python用threading實(shí)現(xiàn)多線程詳解
- python使用threading獲取線程函數(shù)返回值的實(shí)現(xiàn)方法
- Python 使用threading+Queue實(shí)現(xiàn)線程池示例
- Python3 socket即時(shí)通訊腳本實(shí)現(xiàn)代碼實(shí)例(threading多線程)
- python中threading和queue庫(kù)實(shí)現(xiàn)多線程編程
- Python中threading庫(kù)實(shí)現(xiàn)線程鎖與釋放鎖
- Python?threading和Thread模塊及線程的實(shí)現(xiàn)
相關(guān)文章
使用Python的SymPy庫(kù)解決數(shù)學(xué)運(yùn)算問(wèn)題的方法
這篇文章主要介紹了使用Python的SymPy庫(kù)解決數(shù)學(xué)運(yùn)算問(wèn)題的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-03-03使用Python程序抓取新浪在國(guó)內(nèi)的所有IP的教程
這篇文章主要介紹了使用Python程序抓取新浪在國(guó)內(nèi)的所有IP的教程,作為Python網(wǎng)絡(luò)編程中獲取IP的一個(gè)小實(shí)踐,需要的朋友可以參考下2015-05-05Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)實(shí)現(xiàn)優(yōu)先級(jí)隊(duì)列的方法示例
這篇文章主要介紹了Python cookbook(數(shù)據(jù)結(jié)構(gòu)與算法)實(shí)現(xiàn)優(yōu)先級(jí)隊(duì)列的方法,結(jié)合實(shí)例形式分析了Python中基于給定優(yōu)先級(jí)進(jìn)行隊(duì)列元素排序的相關(guān)操作技巧,需要的朋友可以參考下2018-02-02Python使用內(nèi)置函數(shù)setattr設(shè)置對(duì)象的屬性值
這篇文章主要介紹了Python使用內(nèi)置函數(shù)setattr設(shè)置對(duì)象的屬性值,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10詳解Python Celery和RabbitMQ實(shí)戰(zhàn)教程
這篇文章主要介紹了詳解Python Celery和RabbitMQ實(shí)戰(zhàn)教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01python實(shí)現(xiàn)DNS正向查詢、反向查詢的例子
這篇文章主要介紹了python實(shí)現(xiàn)DNS正向查詢、反向查詢的例子,需要的朋友可以參考下2014-04-04詳解python3實(shí)現(xiàn)的web端json通信協(xié)議
本篇文章主要介紹了python3實(shí)現(xiàn)的web端json通信協(xié)議,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-12-12python工具之清理 Markdown 中沒(méi)有引用的圖片
這篇文章主要介紹了python工具之清理 Markdown 中沒(méi)有引用的圖片,文章圍繞主題展開(kāi)詳細(xì)的的內(nèi)容介紹,需要的朋友可以參考一下2022-06-06