Python threading模塊condition原理及運(yùn)行流程詳解
Condition的處理流程如下:
首先acquire一個(gè)條件變量,然后判斷一些條件。
- 如果條件不滿足則wait;
- 如果條件滿足,進(jìn)行一些處理改變條件后,通過notify方法通知其他線程,其他處于wait狀態(tài)的線程接到通知后會(huì)重新判斷條件。
- 不斷的重復(fù)這一過程,從而解決復(fù)雜的同步問題。
Condition的基本原理如下:
可以認(rèn)為Condition對(duì)象維護(hù)了一個(gè)鎖(Lock/RLock)和一個(gè)waiting池。線程通過acquire獲得Condition對(duì)象,當(dāng)調(diào)用wait方法時(shí),線程會(huì)釋放Condition內(nèi)部的鎖并進(jìn)入blocked狀態(tài),同時(shí)在waiting池中記錄這個(gè)線程。當(dāng)調(diào)用notify方法時(shí),Condition對(duì)象會(huì)從waiting池中挑選一個(gè)線程,通知其調(diào)用acquire方法嘗試取到鎖。
Condition對(duì)象的構(gòu)造函數(shù)可以接受一個(gè)Lock/RLock對(duì)象作為參數(shù),如果沒有指定,則Condition對(duì)象會(huì)在內(nèi)部自行創(chuàng)建一個(gè)RLock。
除了notify方法外,Condition對(duì)象還提供了notifyAll方法,可以通知waiting池中的所有線程嘗試acquire內(nèi)部鎖。由于上述機(jī)制,處于waiting狀態(tài)的線程只能通過notify方法喚醒,所以notifyAll的作用在于防止有的線程永遠(yuǎn)處于沉默狀態(tài)。
演示條件變量同步的經(jīng)典問題是生產(chǎn)者與消費(fèi)者問題:假設(shè)有一群生產(chǎn)者(Producer)和一群消費(fèi)者(Consumer)通過一個(gè)市場(chǎng)來交互產(chǎn)品。生產(chǎn)者的”策略“是如果市場(chǎng)上剩余的產(chǎn)品少于1000個(gè),那么就生產(chǎn)100個(gè)產(chǎn)品放到市場(chǎng)上;而消費(fèi)者的”策略“是如果市場(chǎng)上剩余產(chǎn)品的數(shù)量多余100個(gè),那么就消費(fèi)3個(gè)產(chǎn)品。用Condition解決生產(chǎn)者與消費(fèi)者問題的代碼如下:
# -*- coding: utf-8 -*- """ Created on Wed Nov 28 17:15:29 2018 @author: 18665 """ import threading import time class Producer(threading.Thread): # 生產(chǎn)者函數(shù) def run(self): global count while True: if con.acquire(): # 當(dāng)count 小于等于1000 的時(shí)候進(jìn)行生產(chǎn) if count > 1000: con.wait() else: count = count+100 msg = self.name+' produce 100, count=' + str(count) print(msg) # 完成生成后喚醒waiting狀態(tài)的線程, # 從waiting池中挑選一個(gè)線程,通知其調(diào)用acquire方法嘗試取到鎖 con.notify() con.release() time.sleep(1) class Consumer(threading.Thread): # 消費(fèi)者函數(shù) def run(self): global count while True: # 當(dāng)count 大于等于100的時(shí)候進(jìn)行消費(fèi) if con.acquire(): if count < 100: con.wait() else: count = count-5 msg = self.name+' consume 5, count='+str(count) print(msg) con.notify() # 完成生成后喚醒waiting狀態(tài)的線程, # 從waiting池中挑選一個(gè)線程,通知其調(diào)用acquire方法嘗試取到鎖 con.release() time.sleep(1) count = 500 con = threading.Condition() def test(): for i in range(2): p = Producer() p.start() for i in range(5): c = Consumer() c.start() if __name__ == '__main__': test()
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 在Python中通過threading模塊定義和調(diào)用線程的方法
- Python+threading模塊對(duì)單個(gè)接口進(jìn)行并發(fā)測(cè)試
- python threading和multiprocessing模塊基本用法實(shí)例分析
- Python 多線程,threading模塊,創(chuàng)建子線程的兩種方式示例
- Python多線程模塊Threading用法示例小結(jié)
- Python線程threading模塊用法詳解
- Python 多線程之threading 模塊的使用
- Python多線程編程之threading模塊詳解
- python threading模塊的使用指南
- Python常用模塊之threading和Thread模塊及線程通信
相關(guān)文章
python內(nèi)置函數(shù)map/filter/reduce詳解
在Python中,map(), filter(), 和 reduce() 是內(nèi)置的高級(jí)函數(shù)(實(shí)際是class),用于處理可迭代對(duì)象(如列表、元組等)的元素,這篇文章主要介紹了python內(nèi)置函數(shù)map/filter/reduce的相關(guān)知識(shí),需要的朋友可以參考下2024-05-05python調(diào)用有道智云API實(shí)現(xiàn)文件批量翻譯
這篇文章主要介紹了python如何調(diào)用有道智云API實(shí)現(xiàn)文件批量翻譯,幫助大家更好得理解和使用python,感興趣的朋友可以了解下2020-10-10PyTorch實(shí)現(xiàn)圖像識(shí)別實(shí)戰(zhàn)指南
圖像識(shí)別是從給定圖像中提取有意義的信息(例如圖像內(nèi)容)的過程,下面這篇文章主要給大家介紹了關(guān)于PyTorch實(shí)現(xiàn)圖像識(shí)別的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-02-02使用 Python 快速實(shí)現(xiàn) HTTP 和 FTP 服務(wù)器的方法
這篇文章主要介紹了使用 Python 快速實(shí)現(xiàn) HTTP 和 FTP 服務(wù)器 的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07Pytorch相關(guān)知識(shí)介紹與應(yīng)用
最近又重拾了機(jī)器學(xué)習(xí)的相關(guān)技術(shù),在本科畢設(shè)的階段下學(xué)習(xí)使用了Tensorflow 2.x工具,當(dāng)時(shí)也是不求甚解,直接拿來用了,但現(xiàn)在已經(jīng)有充足的時(shí)間、精力和基礎(chǔ)知識(shí)來重新學(xué)習(xí)一下2022-11-11