江湖小白之一起學Python (八)進程池的運用

學習使我快樂…… 接着上篇的講,上篇我們簡單了介紹了多線程的運用,其實在python中多線程是假的多線程,爲什麼這麼說呢,因爲python的解釋器在同一時刻只允許一個線程執行,不管你電腦有幾個核,單位時間多個核只能跑一個線程,然後時間片輪轉,其實可以理解爲在python的多線程是單核多線程,沒有完全利用電腦多核的資源,根本的原因是由全局解釋器鎖(GIL)引起的,要真正利用多核,除非重寫一個不帶GIL的解釋器,有興趣的童鞋可以用多線程寫個無限循環壓力測試看看CPU的運行情況,是否佔滿了100%。

what? 那我們在python中利用多核怎麼辦?所以就有了今天這篇進程池的運用……

python中調用進程池我們要引入對應的庫及方法:

from multiprocessing import Pool

首先我們還是跟多線程一樣定義一個run的方法:

#執行方法
def run(n):
    time.sleep(1)
    print("我是方法:{}".format(n))

爲了觀察方便,我們還是加入了延遲1秒,我們先定義一下進程池:

pool = Pool(processes=4)

processes這個參數表示的工作進程的個數,這個數值是由你電腦的CPU個數決定的,一般這個參數是小於或等於這個CPU數的,如果設置的過大,反而會執行更慢。上面的意思是一次執行4個進程,只要任務沒完,哪個進程先執行完就往這個進程加入新的任務,接下來我們循環生成10個任務:

for i in range(10):
    pool.apply_async(func=run, args=(i, ))

這裏參數的方法跟多線程的方法基本類似,主要就是pool加入進程的方法,下面列舉下一般使用的方式:

1.   apply      (阻塞式的,效果就是跟單進程依次循環一樣)這個意思就是等待當前子進程執行完畢後,在執行下一個進程,個人感覺沒啥用~~!

2.   apply_async  (異步非阻塞式) 這個就是用得最多了,意思就是不用等待當前進程執行完畢,隨時根據系統調度來進行進程切換。

3.   map         這個顧名思義,就是以map函數的形式傳遞參數,通常是數組的形式,比如:

pool.map(func=run,iterable=range(10))
#或者簡寫爲:
pool.map(run,range(10))

4.   map_async   同理這個是map函數以異步非阻塞的形式

apply_async主要是將參數逐個的加入到進程中,平常經常會用到這個,因爲這種方式方便實現一些邏輯代碼,下來來個完整的代碼:

#coding:utf-8
import time
from multiprocessing import Pool

#執行方法
def run(n):
    time.sleep(1)
    print("我是方法:{}".format(n))

#注意:這裏的進程池pool對象定義一定要放在main主模塊下
if __name__ == '__main__':
    #定義進程池
    pool = Pool(processes=4)
    for i in range(10):
        pool.apply_async(func=run, args=(i,))
        #簡寫: pool.apply_async(run, (i,))
    pool.close()   #關閉進程池,不在讓往進程池中添加進程
    pool.join()    #等待進程池中的所有進程執行完畢,必須在close()之後調用

好了,到這裏,進程池的基本用法就這樣了,這樣就通過多進程實現了多核任務,儘量利用計算機的性能資源。後面有興趣的同學還可以自己去了解下多線程與多進程的區別,還有就是協程的用法及優缺點,在這裏我就不再過多的講述了。

認真的時間總是過得這麼快,趕緊動手操作一下看看結果吧!

江湖不說再見,咱們下篇見!

關注公衆號,一起來提高自己吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章