Python多線程(五):線程池

上一篇:生產(chǎn)者消費者問題

在之前的文章中我們一般只演示了兩個線程的情況洪唐,在實際中我們要管理多個線程的時候就需要用到線程池。使用線程池管理線程能夠使主線程可以獲得某一線程的狀態(tài)以及返回值,當一個線程完成的時候主線程就能立知道。

這里我們使用的線程池類是ThreadPoolExecutor识埋,它在concurrent.futures下。concurrent.futures中還包括了ProcessPoolExecutor進程池對象零渐,這個包的設計讓多線程和多進程的接口一致窒舟。

下面是一個例子:

from concurrent.futures import ThreadPoolExecutor
import time

def do_something(name, sec):
    print('Start doing %s' % name)
    time.sleep(sec)
    print('%s completed' % name)
    return name

executor = ThreadPoolExecutor(max_workers=2)
task = executor.submit(do_something, 'A', 2)
print(task.done())
print(task.result())
print(task.done())

運行結果:

Start doing A
False
A completed
A
True

首先需要實例化一個線程池對象,ThreadPoolExecutor類包含一個參數(shù)max_workers诵盼,表示最大同時運行的線程個數(shù)惠豺。線程池中可以田間任意多個線程银还,但是同時能運行的個數(shù)為max_workers,其他線程需要等當前正在運行的max_workers個線程運行完成才能運行洁墙。線程池對象的submit方法可傳入一個函數(shù)句柄及它的參數(shù)见剩,參數(shù)依次排列。一旦調(diào)用submit方法扫俺,線程就已經(jīng)開始執(zhí)行或即將執(zhí)行苍苞,并返回一個Future對象±俏常可調(diào)用Future對象的done方法查看線程是否執(zhí)行完成羹呵,該方法非阻塞。還可以調(diào)用result方法獲得線程的返回值疗琉,該方法阻塞直到線程結束得到返回值冈欢。

如果線程過多,可采用下面的寫法:

from concurrent.futures import ThreadPoolExecutor, as_completed
import random
...

all_task = [executor.submit(do_something, 'task_%d' %i, random.uniform(2,6)) for i in range(10)]
for future in as_completed(all_task):
    data = future.result()
    print(data)

這里的as_completed是一個生成器盈简,它會生成已經(jīng)完成的線程的future對象凑耻。先執(zhí)行完成的線程的future對象會先被生成,直到所有線程結束柠贤,最后一個線程的future對象被生成香浩。從結果來看,由于每次的線程切換不同臼勉,執(zhí)行結果也不同邻吭。

另外還可以用ThreadPoolExecutor對象的map方法查詢線程是否執(zhí)行完成:

for data in executor.map(do_something, ['task_%d' %i for i in range(10)], [random.uniform(2,6) for i in range(10)]):
    print(data)

和之前的as_completed方法不同,map生成器是按照參數(shù)的順序返回的宴霸,但是線程執(zhí)行依然是無序的囱晴。而且map返回的是線程的返回值,不是Future對象瓢谢。在實踐中最常用的還是第一種方法畸写。

concurrent.futures還提供了wait方法,用于阻塞主線程氓扛。其用法是:

from concurrent.futures import wait, ALL_COMPLETED, FIRST_COMPLETED, FIRST_EXCEPTION
wait(fs=all_task, return_when=ALL_COMPLETED)

第一參數(shù)fs是需要等待的線程列表枯芬,還有一個可選參數(shù)是return_when,即停止阻塞的條件幢尚,默認是ALL_COMPLETED破停,即所有線程完成翅楼。除此之外還包括:FIRST_COMPLETED(第一個線程執(zhí)行完成后)尉剩、FIRST_EXCEPTION(在子線程中第一次出現(xiàn)拋出錯誤后)。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末毅臊,一起剝皮案震驚了整個濱河市理茎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖皂林,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朗鸠,死亡現(xiàn)場離奇詭異,居然都是意外死亡础倍,警方通過查閱死者的電腦和手機烛占,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來沟启,“玉大人忆家,你說我怎么就攤上這事〉录#” “怎么了芽卿?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長胳搞。 經(jīng)常有香客問我卸例,道長,這世上最難降的妖魔是什么肌毅? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任筷转,我火速辦了婚禮,結果婚禮上悬而,老公的妹妹穿的比我還像新娘旦装。我一直安慰自己,他們只是感情好摊滔,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布阴绢。 她就那樣靜靜地躺著,像睡著了一般艰躺。 火紅的嫁衣襯著肌膚如雪呻袭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天腺兴,我揣著相機與錄音左电,去河邊找鬼。 笑死页响,一個胖子當著我的面吹牛篓足,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播闰蚕,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼栈拖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了没陡?” 一聲冷哼從身側響起涩哟,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤索赏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后贴彼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體潜腻,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年器仗,在試婚紗的時候發(fā)現(xiàn)自己被綠了融涣。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡精钮,死狀恐怖暴心,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杂拨,我是刑警寧澤专普,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站弹沽,受9級特大地震影響檀夹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜策橘,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一炸渡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丽已,春花似錦蚌堵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嘁灯,卻和暖如春泻蚊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背丑婿。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工性雄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人羹奉。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓秒旋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親诀拭。 傳聞我的和親對象是個殘疾皇子迁筛,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348