使用多線程編程和一個(gè)共享的數(shù)據(jù)結(jié)構(gòu)如 Queue(一種多線程隊(duì)列數(shù)據(jù)結(jié)構(gòu)锥余,先進(jìn)先出/先進(jìn)后出)
1.1棕孙、多線程的構(gòu)成方式:
1.1.1遮婶、UserRequestThread: 負(fù)責(zé)讀取客戶的輸入蹋艺, 可能是一個(gè) I/O 信道儒恋。程序可能創(chuàng)建多個(gè)線程部凑,每個(gè)客戶一個(gè),請(qǐng)求會(huì)被放入隊(duì)列中碧浊。
1.1.2、RequestProcessor: 一個(gè)負(fù)責(zé)從隊(duì)列中獲取并處理請(qǐng)求的線程瘟仿, 它為下面那種線程提供輸出箱锐。
1.1.3、ReplyThread: 負(fù)責(zé)把給用戶的輸出取出來劳较,如果是網(wǎng)絡(luò)應(yīng)用程序就把結(jié)果發(fā)送出去驹止,否則就保存到本地文件系統(tǒng)或數(shù)據(jù)庫中。
Python观蜗、線程和全局解釋器鎖
1.2臊恋、全局解釋器鎖(GIL)
Python 代碼的執(zhí)行由 Python 虛擬機(jī)(也叫解釋器主循環(huán))來控制。Python 在設(shè)計(jì)之初就考慮到要在主循環(huán)中墓捻,同時(shí)只有一個(gè)線程在執(zhí)行抖仅,也就是偽多線程。
1.2.1砖第、對(duì) Python 虛擬機(jī)的訪問由全局解釋器鎖(GIL)來控制撤卢,在多線程環(huán)境中,Python 虛擬機(jī)按以下方式執(zhí)行:
1.2.2梧兼、Python 提供了幾個(gè)用于多線程編程的模塊放吩,包括 thread, threading 和 Queue 等。thread 和threading 模塊允許程序員創(chuàng)建和管理線程羽杰。thread 模塊提供了基本的線程和鎖的支持渡紫,而 threading提供了更高級(jí)別到推,功能更強(qiáng)的線程管理的功能。Queue 模塊允許用戶創(chuàng)建一個(gè)可以用于多個(gè)線程之間共享數(shù)據(jù)的隊(duì)列數(shù)據(jù)結(jié)構(gòu)
threading 模塊
1.3.惕澎、守護(hù)線程
1.3.1莉测、threading 模塊支持守護(hù)線程, 它們是這樣工作的: 守護(hù)線程一般是一個(gè)等待客戶請(qǐng)求的服務(wù)器集灌,如果沒有客戶提出請(qǐng)求悔雹,它就在那等著。如果你設(shè)定一個(gè)線程為守護(hù)線程欣喧,就表示你在說這個(gè)線程是不重要的腌零,在進(jìn)程退出的時(shí)候,不用等待這個(gè)線程退出唆阿。
1.3.2益涧、設(shè)置守護(hù)線程的方法:
在線程開始(調(diào)用 thread.start())之前, 調(diào)用 setDaemon()函數(shù)設(shè)定線程的 daemon 標(biāo)志(thread.setDaemon(True)) 就表示這個(gè)線程“不重要”
1.3.3驯鳖、對(duì)于非守護(hù)線程闲询,可以顯式地調(diào)用thread.setDaemon(False)以保證其 daemon 標(biāo)志為 False。 也可以調(diào)用 thread.isDaemon()函數(shù)來判斷其 daemon 標(biāo)志的值浅辙。新的子線程會(huì)繼承其父線程的 daemon 標(biāo)志扭弧。
1.3.4、整個(gè) Python 會(huì)在所有的非守護(hù)線程退出后才會(huì)結(jié)束,即進(jìn)程中沒有非守護(hù)線程存在的時(shí)候才結(jié)束记舆。
1.4鸽捻、threading.Thread類
1.4.1御蒲、threading 模塊中的其它函數(shù)
1.5、生產(chǎn)者-消費(fèi)者問題和 Queue 模塊
1.5.1诊赊、線程同步(鎖)
多線程的優(yōu)勢(shì)在于可以同時(shí)運(yùn)行多個(gè)任務(wù)厚满,至少感覺起來是這樣,但是當(dāng)線程需要共享數(shù)據(jù)時(shí)碧磅,可能存在數(shù)據(jù)不同步的問題碘箍。
1.5.2、#構(gòu)造方法:
Thread(group=None,target=None,name=None,args=(),kwargs={})
group:線程組鲸郊,目前還沒有實(shí)現(xiàn)敲街,庫引用時(shí)提示必須是None
target:要執(zhí)行的方法
name:線程名
args/kwargs:要傳入方法的參數(shù),args和kwargs兩個(gè)參數(shù)其實(shí)是二選一
Lock():lock是可用的最低級(jí)的同步指令严望,Lock處于鎖定狀態(tài)時(shí)多艇,不被特定的線程擁有,Lock包含2種狀態(tài)--鎖定和非鎖定以及2個(gè)基本的方法
1.5.3像吻、#實(shí)例方法
isAlive():返回線程是否在運(yùn)行
get/setName(name):獲取/設(shè)置線程名
is/setDaemon(bool):獲取/設(shè)置是否守護(hù)線程峻黍。初始值從創(chuàng)建該線程的線程繼承复隆,當(dāng)沒有非守護(hù)線程仍在運(yùn)行時(shí),程序?qū)⒔K止
start():啟動(dòng)線程
join([timeout]):阻塞當(dāng)前上下文環(huán)境的線程姆涩。
acquire([timeout]):使線程進(jìn)入同步阻塞狀態(tài)挽拂,嘗試獲得鎖定
release():釋放鎖,使用前線程必須已獲得鎖定骨饿,否則將拋出異常