Python獲取多進程執(zhí)行的返回值實現(xiàn)
眾所周知,因為GIL的原因,Python至今不支持真正的多線程。為了達到并行運行的目的,我們往往就需要運行多進程了。
一個任務(wù)由一個進程來運行,可是它的結(jié)果怎么來獲取呢?
方法-1.
第一種方法是記錄在全局變量中。當然這時候要注意可能會需要用到Lock. 下面是一個例子。
Program-1
import multiprocessing
from multiprocessing import Pool
info_manager = multiprocessing.Manager()
info_lock = info_manager.Lock()
info_dict = info_manager.dict()
def add(n):
? ? global info_dict, info_lock?
? ??
? ? s = 0
? ? for i in range(n+1):
? ? ? ? s += i
? ??
? ? info_lock.acquire()
? ? info_dict[n] = s
? ? info_lock.release()
? ??
? ? print("In task %d: %d -> %d" % (n, n, s))
def calculate():
? ? pool = Pool(processes=4)?
? ? tasks = range(10)
? ? for n in tasks:
? ? ? ? pool.apply_async(add, (n,))
? ? ? ??
? ? pool.close()
? ? pool.join()
? ??
? ??
def print_result():
? ? global info_dict
? ??
? ? key_list = sorted(info_dict.keys())
? ??
? ? for key in key_list:
? ? ? ? print("%s: %s" % (key, info_dict[key]))?
? ??
? ??
if __name__ == '__main__':
? ? calculate()
? ? print_result()除了使用全局變量,還有沒有其他的方法呢?畢竟全局變量似乎看起來有點危險,不小心就會被弄壞。
方法-2.
第二種方法,就是記錄下multiprocessing.Pool.apply_async的返回值(假設(shè)稱之為result),然后在Pool被join之后,利用result.get()方法來得到原任務(wù)函數(shù)的返回值。在這里,multiprocessing.Pool.apply_async的返回值的類型是multiprocessing.pool.ApplyResult,其get()方法會返回原任務(wù)函數(shù)的返回值。
下面是把上面的那個例子重新寫一遍。
Program-2
import multiprocessing
from multiprocessing import Pool
def add(n):
? ? s = 0
? ? for i in range(n+1):
? ? ? ? s += i
? ? return (n, s)
def calculate():
? ? pool = Pool(processes=4)
? ? tasks = range(10)
? ? result_list = list()
? ? info_dict = dict()
? ??
? ? for n in tasks:
? ? ? ? result_list.append(pool.apply_async(add, (n,)))
? ? ? ??
? ? pool.close()
? ? pool.join()
? ??
? ? for result in result_list:
? ? ? ? k, v = result.get()
? ? ? ? info_dict[k] = v
? ? ? ??
? ? return info_dict
? ??
? ??
def print_result():
? ? info_dict = calculate()
? ??
? ? key_list = sorted(info_dict.keys())
? ??
? ? for key in key_list:
? ? ? ? print("%s: %s" % (key, info_dict[key]))?
? ??
? ??
if __name__ == '__main__':
? ? calculate()
? ? print_result()另外,其實也可以不用等到 Pool join 之后才能調(diào)get(). 可以立刻調(diào)用get(), 但這可能會造成阻塞。
而get()函數(shù)其實有一個參數(shù),可以指定超時時間以免無限等下去,如,result.get(timeout=2), 就是設(shè)置超時為2秒。
其定義在Python3中如下:
get([timeout])
Return the result when it arrives.
If timeout is not None and the result does not arrive within timeout seconds
then multiprocessing.TimeoutError is raised.
If the remote call raised an exception then that exception will be reraised by get().
也就是說,如果超時了,就會拋出一個multiprocessing.TimeoutError異常;
而如果該任務(wù)進程內(nèi)拋了異常,也會被get()重新拋出來。
本文程序通過Python2和Python3的測試。
到此這篇關(guān)于Python獲取多進程執(zhí)行的返回值實現(xiàn)的文章就介紹到這了,更多相關(guān)Python獲取多進程執(zhí)行的返回值內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在vscode中啟動conda虛擬環(huán)境的思路詳解
這篇文章主要介紹了在vscode中啟動conda虛擬環(huán)境的思路詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
Python實現(xiàn)Smtplib發(fā)送帶有各種附件的郵件實例
本篇文章主要介紹了Python實現(xiàn)Smtplib發(fā)送帶有各種附件的郵件實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06

