Python中多線程的創(chuàng)建及基本調(diào)用方法
1. 多線程的作用
簡(jiǎn)而言之,多線程是并行處理相互獨(dú)立的子任務(wù),從而大幅度提高整個(gè)任務(wù)的效率。
2. Python中的多線程相關(guān)模塊和方法
Python中提供幾個(gè)用于多線程編程的模塊,包括thread,threading和Queue等
thread模塊提供了基本的線程和鎖的支持,除產(chǎn)生線程外,也提供基本的同步數(shù)據(jù)結(jié)構(gòu)鎖對(duì)象,其中包括:
start_new_thread(function, args kwargs=None) 產(chǎn)生一個(gè)新的線程來運(yùn)行給定函數(shù)
allocate_lock() 分配一個(gè)LockType類型的鎖對(duì)象
exit() 讓線程退出
acquire(wait=None) 嘗試獲取鎖對(duì)象
locked() 如果獲取了鎖對(duì)象返回TRUE,否則返回FALSE
release() 釋放鎖
threading提供了更高級(jí)別,功能更強(qiáng)的線程管理功能
Thread類 表示一個(gè)線程的執(zhí)行的對(duì)象
Lock 鎖原語對(duì)象
RLock 可重入鎖對(duì)象,使單線程可以再次獲得已經(jīng)獲取鎖
queue模塊允許用戶創(chuàng)建一個(gè)可以用于多個(gè)線程之間共享數(shù)據(jù)的隊(duì)列數(shù)據(jù)結(jié)構(gòu)
可用于進(jìn)程間的通訊,讓各個(gè)線程之間共享數(shù)據(jù)
模塊函數(shù)queue(size) 創(chuàng)建一個(gè)大小為size的Queue對(duì)象
queue對(duì)象函數(shù) qsize() 返回隊(duì)列大小
empty() 隊(duì)列為空返回True,否則返回False
put(item, block=0) 把ITEM放到隊(duì)列中,block不為0,函數(shù)會(huì)一直阻塞到隊(duì)列中
get(block=0) 從隊(duì)列中取一個(gè)對(duì)象,若果給block,函數(shù)會(huì)一直阻塞到隊(duì)列中有對(duì)象為止
3.示例
目前Python的lib中對(duì)多線程編程提供兩種啟動(dòng)方法,一種是比較基本的thread模塊中start_new_thread方法,在線程中運(yùn)行一個(gè)函數(shù), 另一種是使用集成threading模塊的線程對(duì)象Thread類。
目前所用到的,是舊版本中調(diào)用thread模塊中的start_new_thread()函數(shù)來產(chǎn)生新的線程
相比而言,thread.start_new_thread(function,(args[,kwargs]))實(shí)現(xiàn)機(jī)制其實(shí)與C更為類似,其中function參數(shù)是將要調(diào)用的線程函數(shù);(args[,kwargs])是將傳遞給待創(chuàng)建線程函數(shù)的參數(shù)組成的元組類型,其中kwargs是可選的參數(shù)。新創(chuàng)建的線程結(jié)束一般依靠線程函數(shù)的執(zhí)行結(jié)束自動(dòng)退出,或者在線程函數(shù)中調(diào)用thread.exit()拋出SystemExit exception,達(dá)到線程退出的目的。
print "=======================thread.start_new_thread啟動(dòng)線程=============" import thread #Python的線程sleep方法并不是在thread模塊中,反而是在time模塊下 import time def inthread(no,interval): count=0 while count<10: print "Thread-%d,休眠間隔:%d,current Time:%s"%(no,interval,time.ctime()) #使當(dāng)前線程休眠指定時(shí)間,interval為浮點(diǎn)型的秒數(shù),不同于Java中的整形毫秒數(shù) time.sleep(interval) #Python不像大多數(shù)高級(jí)語言一樣支持++操作符,只能用+=實(shí)現(xiàn) count+=1 else: print "Thread-%d is over"%no #可以等待線程被PVM回收,或主動(dòng)調(diào)用exit或exit_thread方法結(jié)束線程 thread.exit_thread() #使用start_new_thread函數(shù)可以簡(jiǎn)單的啟動(dòng)一個(gè)線程,第一個(gè)參數(shù)指定線程中執(zhí)行的函數(shù),第二個(gè)參數(shù)為元組型的傳遞給指定函數(shù)的參數(shù)值 thread.start_new_thread(inthread,(1,2)) #線程執(zhí)行時(shí)必須添加這一行,并且sleep的時(shí)間必須足夠使線程結(jié)束,如本例 #如果休眠時(shí)間改為20,將可能會(huì)拋出異常 time.sleep(30) '''
使用這種方法啟動(dòng)線程時(shí),有可能出現(xiàn)異常
Unhandled exception in thread started by Error in sys.excepthook: Original exception was:
解決:?jiǎn)?dòng)線程之后,須確保主線程等待所有子線程返回結(jié)果后再退出,如果主線程比子線程早結(jié)束,無論其子線程是否是后臺(tái)線程,都將會(huì)中斷,拋出這個(gè)異常
若沒有響應(yīng)阻塞等待,為避免主線程提前退出,必須調(diào)用time.sleep使主線程休眠足夠長(zhǎng)的時(shí)間,另外也可以采用加鎖機(jī)制來避免類似情況,通過在啟動(dòng)線程的時(shí)候,給每個(gè)線程都加了一把鎖,直到線程運(yùn)行介紹,再釋放這個(gè)鎖。同時(shí)在Python的main線程中用一個(gè)while循環(huán)來不停的判斷每個(gè)線程鎖已釋放。
import thread; from time import sleep,ctime; from random import choice #The first param means the thread number #The second param means how long it sleep #The third param means the Lock def loop(nloop,sec,lock): print "Thread ",nloop," start and will sleep ",sec; sleep(sec); print "Thread ",nloop," end ",sec; lock.release(); def main(): seconds=[4,2]; locks=[]; for i in range(len(seconds)) : lock=thread.allocate_lock(); lock.acquire(); locks.append(lock); print "main Thread begins:",ctime(); for i,lock in enumerate(locks): thread.start_new_thread(loop,(i,choice(seconds),lock)); for lock in locks : while lock.locked() : pass; print "main Thread ends:",ctime(); if __name__=="__main__" : main();
很多介紹說在新python版本中推薦使用Threading模塊,目前暫沒有應(yīng)用到。。。
相關(guān)文章
python中parser.add_argument()用法實(shí)例(命令行選項(xiàng)、參數(shù)和子命令解析器)
最近開始讀論文代碼了,遇到一個(gè)名字叫option的py文件,打開一看清一色的parser.add_argument(),看得是一臉懵逼,這篇文章主要給大家介紹了關(guān)于python中parser.add_argument()用法的相關(guān)資料,需要的朋友可以參考下2022-03-03Python的Flask框架中配置多個(gè)子域名的方法講解
Fask中可以通過通配符子域的方式來部署多個(gè)子域名,這里我們就來作一個(gè)Python的Flask框架中配置多個(gè)子域名的方法講解,需要的朋友可以參考下2016-06-06Python編程之gui程序?qū)崿F(xiàn)簡(jiǎn)單文件瀏覽器代碼
這篇文章主要介紹了Python編程之gui程序?qū)崿F(xiàn)簡(jiǎn)單文件瀏覽器代碼,具有一定借鑒價(jià)值,需要的朋友可以了解下。2017-12-12python實(shí)現(xiàn)使用遺傳算法進(jìn)行圖片擬合
最近做項(xiàng)目需要圖像擬合,本文主要介紹了python實(shí)現(xiàn)使用遺傳算法進(jìn)行圖片擬合,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Python3.7安裝PyQt5 運(yùn)行配置Pycharm的詳細(xì)教程
這篇文章主要介紹了Python3.7成功安裝心得PyQt5 PyQt5-tools QT designer.exe運(yùn)行配置Pycharm 將.ui文件翻譯成.py文件,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2020-10-10Python詳解文字轉(zhuǎn)語音的實(shí)現(xiàn)
在自然語言處理上,文字、音頻互轉(zhuǎn)是一個(gè)很關(guān)鍵的技術(shù)點(diǎn)。對(duì)于語音轉(zhuǎn)文字,個(gè)人實(shí)現(xiàn)較為困難,我們可以使用語音轉(zhuǎn)文字的軟件或借助各API(如科大訊飛等)進(jìn)行移植開發(fā)。不過文字轉(zhuǎn)語音就相對(duì)而言容易實(shí)現(xiàn)很多了2022-02-02Django框架視圖函數(shù)設(shè)計(jì)示例
這篇文章主要介紹了Django框架視圖函數(shù)設(shè)計(jì),結(jié)合實(shí)例形式分析了Django框架視圖函數(shù)處理流程、原理與相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-07-07python的ImageTk.PhotoImage大坑及解決
這篇文章主要介紹了python的ImageTk.PhotoImage大坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11