Python多進程入門(3Pool)

這篇文章簡單介紹一下multiprocessing包中的進程池程管理工具Pool。如果你是第一次接觸python的多進程年碘,請先看一下我的前兩篇文章http://www.reibang.com/p/31bca20caec0http://www.reibang.com/p/e7a5f3b2afcf傲诵。如果只想了解Pool栓拜,那就接著看吧。在上一篇文章中我們介紹了Process的主要應(yīng)用,使用Process可以建立一個進程盛险,如果建立多個進程可以使用多個Process建立不同的的進程對象揉忘,也可以使用for循環(huán)建立多個進程换淆,具體內(nèi)容請看我在簡書的上一篇文章。

我們引入進程池工具Pool,直接把進程扔到池里,根據(jù)池自身的特點對進程進行管理样勃,后面我會詳細(xì)介紹峭拘,這里只需要知道他是一個容器能夠夠使制定數(shù)量的進程在池中統(tǒng)一運行即可鸡挠,下面來看一段簡單的代碼:

#  多個進程同時運行沒有返回值
def f(name):
    """定義一個簡單的打印名字的函數(shù)"""
    print('hello:', name)


if __name__ == '__main__':
    name_list = ["小飛", "小倩", "是不是淘氣", "二妞"]
    pool = Pool(processes=4)  # 創(chuàng)建4個進程
    for name in name_list:
        pool.apply_async(f, (name,))
    pool.close()  # 關(guān)閉進程池姓惑,表示不能在往進程池中添加進程
    pool.join()  # 等待進程池中的所有進程執(zhí)行完畢唯沮,必須在close()之后調(diào)用


返回的結(jié)果為:
hello: 小飛
hello: 小倩
hello: 是不是淘氣
hello: 二妞

在上面的例子中我們使用Pool建立了一個可以存放四個進程的池于游,使用for循環(huán),將進程依次加入到進程池中担忧,對于每一個進程使用apply_async()方法建立進程芹缔。對于進程池Pool這個類,主要有兩種建立進程的方式一種是apply_async()瓶盛,另一種是map()最欠,這兩種類方法的解釋如下:

apply_async函數(shù)原型:

apply_async(func[, args=()[, kwds={}[, callback=None]]])
與apply用法一樣,但它是非阻塞且支持結(jié)果返回進行回調(diào)惩猫。

map 函數(shù)原型:

map(func, iterable[, chunksize=None])
Pool類中的map方法芝硬,與內(nèi)置的map函數(shù)用法行為基本一致,它會使進程阻塞直到返回結(jié)果轧房。
注意拌阴,雖然第二個參數(shù)是一個迭代器,但在實際使用中奶镶,必須在整個隊列都就緒后迟赃,程序才會運行子進程。

之前對close实辑、terminate捺氢、join方法已經(jīng)有了介紹,這里在介紹一次:

close()

關(guān)閉進程池(pool)剪撬,使其不在接受新的任務(wù)摄乒。

terminate()

結(jié)束工作進程,不在處理未處理的任務(wù)残黑。

join()

主進程阻塞等待子進程的退出馍佑,join方法必須在close或terminate之后使用。
上面的案例中梨水,每個進程都沒有返回值拭荤,下面介紹一個有返回值的,先看一下代碼疫诽,我再來解釋:

#  多個進程同時運行舅世,每個進程都有返回值
def add_part(part):
    """計算一個列表的開始到末尾的累加
    :param part:長度為二的列表
    :return: 返回累加的和
    """
    result = 0
    for value in range(part[0], part[1] + 1):
        result += value
    return result


if __name__ == '__main__':
    #  第一種方式使用pool.apply_async(),使用pool.get()來獲取結(jié)果
    startTime = datetime.datetime.now()
    part_result = []
    pool = Pool(processes=2)
    for i in [[0, 500000000], [500000001, 1000000000]]:
        part_result.append(pool.apply_async(add_part, (i,)))
    pool.close()
    pool.join()
    add_result = 0
    for index, value in enumerate(part_result, 0):
        print("第%s個進程的結(jié)果為%s" % (index, value.get()))
        add_result += value.get()
    print("結(jié)果為", add_result)
    print(datetime.datetime.now() - startTime)

這里我們繼續(xù)使用我們的老例子,將一個累加的過程分成兩個進程奇徒,這里我就不對案例的過程詳細(xì)介紹了雏亚,如果沒看懂的先出門看一下我前面的兩篇文章:http://www.reibang.com/p/31bca20caec0http://www.reibang.com/p/e7a5f3b2afcf。這里我主要介紹一下和之前不同的地方摩钙,這里是有返回值的罢低,我們在上面的程序中使用 part_result = []來存儲我們建立的進程,后面我們在使用for循環(huán)遍歷這個存儲進程的列表胖笛,使用get()方法得到進程的結(jié)果并將其累加网持。我們來看一些結(jié)果:

第0個進程的結(jié)果為125000000250000000
第1個進程的結(jié)果為375000000250000000
結(jié)果為 500000000500000000
0:00:34.825516

上面的例子中我們使用了Pool來對有返回的進程距離一個例子宜岛,但是這里使用了get()來收集進程的返回值,下面我們來使用map()方法來直接收集進程返回的結(jié)果功舀,上代碼:

def add_part(part):
    """計算一個列表的開始到末尾的累加
    :param part:長度為二的列表
    :return: 返回累加的和
    """
    result = 0
    for value in range(part[0], part[1] + 1):
        result += value
    return result


if __name__ == '__main__':
#  第二種方式使用pool.map(),直接獲取所有進程的結(jié)果獲取結(jié)果
    startTime = datetime.datetime.now()
    pool = Pool(processes=2)
    part_result = (pool.map(add_part, [[0, 500000000], [500000001, 1000000000]]))
    pool.close()
    pool.join()
    print(part_result)
    add_result = 0
    for i in part_result:
        print(i)
        add_result += i
    print("結(jié)果為:", add_result)
    print(datetime.datetime.now() - startTime)


運行結(jié)果為:
[125000000250000000, 375000000250000000]
125000000250000000
375000000250000000
結(jié)果為: 500000000500000000
0:00:32.576957

我們來看一下上面的代碼萍倡,我們使用了map()方法直接將進程的結(jié)果輸出到part_result 列表中。下一篇文章中我們繼續(xù)介紹多個線程之間的數(shù)據(jù)交互日杈。

?著作權(quán)歸作者所有,轉(zhuǎ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
  • 正文 為了忘掉前任韩脏,我火速辦了婚禮缩麸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赡矢。我一直安慰自己杭朱,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布吹散。 她就那樣靜靜地躺著痕檬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪送浊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天丘跌,我揣著相機與錄音袭景,去河邊找鬼唁桩。 笑死,一個胖子當(dāng)著我的面吹牛耸棒,可吹牛的內(nèi)容都是我干的荒澡。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼与殃,長吁一口氣:“原來是場噩夢啊……” “哼单山!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起幅疼,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤米奸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后爽篷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悴晰,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年逐工,在試婚紗的時候發(fā)現(xiàn)自己被綠了铡溪。 大學(xué)時的朋友給我發(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
  • 正文 我出身青樓篓跛,卻偏偏與公主長得像膝捞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子愧沟,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容