Python線程協(xié)作threading.Condition實(shí)現(xiàn)過程解析
領(lǐng)會(huì)下面這個(gè)示例吧,其實(shí)跟java中wait/nofity是一樣一樣的道理
import threading
# 條件變量,用于復(fù)雜的線程間同步鎖
"""
需求:
男:小姐姐,你好呀!
女:哼,想泡老娘不成?
男:對(duì)呀,想泡你
女:滾蛋,門都沒有!
男:切,長這么丑, 還這么吊...
女:關(guān)你鳥事!
"""
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("{}:切,長這么丑, 還這么吊...".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("{}:滾蛋,門都沒有!".format(self.name))
self.condition.notify()
self.condition.wait()
print("{}:關(guān)你鳥事!".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庫實(shí)現(xiàn)多線程編程
- Python中threading庫實(shí)現(xiàn)線程鎖與釋放鎖
- Python?threading和Thread模塊及線程的實(shí)現(xiàn)
相關(guān)文章
Python使用ThreadPoolExecutor一次開啟多個(gè)線程
通過使用ThreadPoolExecutor,您可以同時(shí)開啟多個(gè)線程,從而提高程序的并發(fā)性能,本文就來介紹一下Python使用ThreadPoolExecutor一次開啟多個(gè)線程,感興趣的可以了解一下2023-11-11
web.py 十分鐘創(chuàng)建簡(jiǎn)易博客實(shí)現(xiàn)代碼
web.py是一款輕量級(jí)的Python web開發(fā)框架,簡(jiǎn)單、高效、學(xué)習(xí)成本低,特別適合作為python web開發(fā)的入門框架2016-04-04
Python常見MongoDB數(shù)據(jù)庫操作實(shí)例總結(jié)
這篇文章主要介紹了Python常見MongoDB數(shù)據(jù)庫操作,結(jié)合實(shí)例形式詳細(xì)總結(jié)了Python針對(duì)MongoDB數(shù)據(jù)庫相關(guān)pymongo庫安裝以及MongoDB數(shù)據(jù)庫的增刪改查等相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-07-07
nx.adjacency_matrix計(jì)算鄰接矩陣與真實(shí)結(jié)果不一致的解決
這篇文章主要介紹了nx.adjacency_matrix計(jì)算鄰接矩陣與真實(shí)結(jié)果不一致的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
Python遍歷指定文件夾下的所有文件名的方法小結(jié)
當(dāng)需要遍歷指定文件夾下的所有文件名時(shí),Python提供了多種方法來實(shí)現(xiàn)這個(gè)任務(wù),本文將介紹如何使用Python來完成這一任務(wù),有需要的小伙伴可以參考下2024-01-01
python統(tǒng)計(jì)mysql數(shù)據(jù)量變化并調(diào)用接口告警的示例代碼
這篇文章主要介紹了python統(tǒng)計(jì)mysql數(shù)據(jù)量變化并調(diào)用接口告警的示例代碼,幫助大家更好的利用python操作數(shù)據(jù)庫,感興趣的朋友可以了解下2020-09-09
通過實(shí)例解析Python return運(yùn)行原理
這篇文章主要介紹了通過實(shí)例解析Python return運(yùn)行原理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
python 內(nèi)置庫wsgiref的使用(WSGI基礎(chǔ)入門)
WSGI(web服務(wù)器網(wǎng)關(guān)接口)主要規(guī)定了服務(wù)器端和應(yīng)用程序之間的接口,即規(guī)定了請(qǐng)求的URL到后臺(tái)處理函數(shù)之間的映射該如何實(shí)現(xiàn)。wsgiref是一個(gè)幫助開發(fā)者開發(fā)測(cè)試的Python內(nèi)置庫,程序員可以通過這個(gè)庫了解WSGI的基本運(yùn)行原理,但是不能把它用在生產(chǎn)環(huán)境上。2021-06-06
python實(shí)現(xiàn)AES和RSA加解密的方法
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)AES和RSA加解密的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03
python爬取分析超級(jí)大樂透歷史開獎(jiǎng)數(shù)據(jù)
這篇文章主要介紹了python爬取分析超級(jí)大樂透歷史開獎(jiǎng)數(shù)據(jù),本次使用了requests和beautifulsoup庫進(jìn)行數(shù)據(jù)的爬取,通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02

