在學習python多進程時,進程上運行的方法接收多個參數和多個結果時遇到了問題,現在經過學習在這里總結一下
Pool.map()多參數任務
在給map方法傳入帶多個參數的方法不能達到預期的效果,像下面這樣
def job(x ,y):
return x * y
if __name__ == "__main__":
pool = multiprocessing.Pool()
res = pool.map(job, 2, 3)
print res
所以只能通過對有多個參數的方法進行封裝,在進程中運行封裝后的方法如下
def job(x ,y):
return x * y
def job1(z):
return job(z[0], z[1])
if __name__ == "__main__":
pool = multiprocessing.Pool()
res = pool.map(job1, [(2, 3), (3, 4)])
print res
這樣就能達到傳遞多個參數的效果
ps:如果需要得到多個結果可以傳入多個元組在一個列表中
Pool.apply_async()輸出多個迭代結果
在使用apply_async()方法接收多個參數的方法時,在任務方法中正常定義多個參數,參數以元組形式傳入即可
但是給apply_async()方法傳入多個值獲取多個迭代結果時就會報錯,因為該方法只能接收一個值,所以可以將該方法放入一個列表生成式中,如下
def job(x):
return x * x
if __name__ == "__main__":
pool multiprocessing.Pool()
res = [pool.apply_async(target=job, (i,)) for i in range(3)]
print [r.get() for r in res]
當想要提高一個任務的執行效率時,我們可以通過拆分任務,把這個任務拆分成多個子任務,然后利用多進程進行異步執行,即同時處理,縮短整體的任務時間。在python的multiprocessing包中,有兩個可以構造異步執行的進程任務方法,apply_async()和map_async(),兩者都可以分別添加任務,然后多進程同時執行。但是兩者有着重要區別,下面進行說明。
對於apply_async(func,args),func為要執行任務的函數名,args為一個列表或元組這樣的可迭代對象,里面包含的是要傳遞給func的參數,對於多個子任務,要分別多次調用apply_async()一一添加,不過這可以通過列表解析實現,以讓多個進程的結果返回保存在一個列表中。而對於map_async(func,iterable,chunksize),如果多個子任務通過同一函數執行,只是參數不同,那么可以把拆分后的參數以列表形式通過iterable傳入,並通過chunksize參數指定進程數(實際上這里的chunksize表示的是對iterable的拆分數,但最好讓其等於進程數),這樣就不需要一一添加。
以上只是兩者細微的差別,更重要的差別在於,若是通過apply_async()方法,由於是手動指定進程並添加任務,這樣每個進程的執行結果之間是獨立的,會分別保存,這樣的好處在於,盡管可能其中某幾個進程出現了錯誤,拋出異常,但是並不會導致其他的進程也失敗,其他的進程並不會受影響,而且當獲取這個拋出異常的進程的結果時,還會返回異常信息;但是如果是map_async()方法,其子參數任務並不是獨立的,如果其中的某個子參數任務拋出異常,同時也會導致其他的子參數任務停止,也就是說,並不是通過獨立線程來執行不同的子參數任務的。
通過上述的對比,可知當拆分任務一提高執行效率時,通過列表解析使用apply_async()方法添加子任務,使用獨立多進程去執行是比map_async()方法更好的,因此這種情況下,apply_async()是最優選擇。