multiprocessing

multiprocessing模塊

如果你打算編寫多進程的服務程序,Unix/Linux無疑是正確的選擇。由於Windows沒有fork調用,難道在Windows上無法用Python編寫多進程的程序?由於Python是跨平臺的,自然也應該提供一個跨平臺的多進程支持。multiprocessing模塊就是跨平臺版本的多進程模塊。multiprocessing模塊提供了一個Process類來代表一個進程對象,這個模塊表示像線程一樣管理進程,這個是multiprocessing的核心,它與threading很相似,對多核CPU的利用率會比threading好的多。

 看一下Process類的構造方法:

__init__(self, group=None, target=None, name=None, args=(), kwargs={})

參數說明: 
group:進程所屬組。基本不用 
target:表示調用對象。 
args:表示調用對象的位置參數元組。 
name:別名 
kwargs:表示調用對象的字典。

創建子進程時,只需要傳入一個執行函數和函數的參數,創建一個Process實例,並用其start()方法啓動,這樣創建進程比fork()還要簡單。 join()方法表示等待子進程結束以後再繼續往下運行,通常用於進程間的同步。

注意: 
在Windows上要想使用進程模塊,就必須把有關進程的代碼寫在當前.py文件的if __name__ == ‘__main__’ :語句的下面,才能正常使用Windows下的進程模塊。Unix/Linux下則不需要。

Pool類

 Pool類可以提供指定數量的進程供用戶調用,當有新的請求提交到Pool中時,如果池還沒有滿,就會創建一個新的進程來執行請求。如果池滿,請求就會告知先等待,直到池中有進程結束,纔會創建新的進程來執行這些請求。 
下面介紹一下multiprocessing 模塊下的Pool類下的幾個方法:

.apply()

函數原型:apply(func[, args=()[, kwds={}]])

該函數用於傳遞不定參數,同python中的apply函數一致,主進程會被阻塞直到函數執行結束(不建議使用,並且3.x以後不在出現)。

.apply_async

函數原型:apply_async(func[, args=()[, kwds={}[, callback=None]]])

與apply用法一致,但它是非阻塞的且支持結果返回後進行回調。

.map()

 函數原型:map(func, iterable[, chunksize=None])

Pool類中的map方法,與內置的map函數用法行爲基本一致,它會使進程阻塞直到結果返回。 
注意:雖然第二個參數是一個迭代器,但在實際使用中,必須在整個隊列都就緒後,程序纔會運行子進程。

.map_async()

函數原型:map_async(func, iterable[, chunksize[, callback]])
與map用法一致,但是它是非阻塞的。其有關事項見apply_async。

.close()

關閉進程池(pool),使其不在接受新的任務。

.terminal()

結束工作進程,不在處理未處理的任務。

.join()

主進程阻塞等待子進程的退出, join方法要在close或terminate之後使用。

    apply_async(func[, args[, kwds]]) :使用非阻塞方式調用func(並行執行,堵塞方式必須等待上一個進程退出才能執行下一個進程),args爲傳遞給func的參數列表,kwds爲傳遞給func的關鍵字參數列表;異步,多個線程同時執行

    apply(func[, args[, kwds]]):使用阻塞方式調用func,執行完一個進程後再去執行其他線程。

    close():關閉Pool,使其不再接受新的任務;

    terminate():不管任務是否完成,立即終止;

    join():主進程阻塞,等待子進程的退出, 必須在close或terminate之後使用;

    apply_async(func, args=(), kwds={}, callback=None, error_callback=None):callback:回調函數,可接收func函數的返回值

.注意點: 主進程不會等待子進程結束後,再結束。需要加join()

    join()必須放在close語句之後
 

#!/usr/bin/python
# --*-- coding:utf-8 --*--
import multiprocessing
import sys,os,time
result = []#把運行的進程池放入,空的列表
def run(msg):#定義正在處理進程編號數的函數功能
    #打印正在處理的進程編號數與對應的系統進程號
    print ('threading number:%s %s' %(msg,os.getpid()))
    time.sleep(2)
p = multiprocessing.Pool(processes = 25)#綁定事例,同時執行25個線程

for i in range(100):
    result.append(p.apply_async(run,('%s' %i,)))#異步傳輸正在運行的進程數字號碼

p.close()#關閉正在運行的25個進程
#p.join()

for res in result:#獲取運行結果
    res.get(timeout=5)

 

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