[英]Python run function parallel
我想運行一個“主要”功能n次。 該功能在運行時會啟動其他功能。 “主要”功能稱為“重復”,運行時首先啟動功能“ copula_sim”,然后從那里獲得名為“ total_summe_liste”的輸出。 該列表將被添加到“ mega_summe_list”中,以確保n次運行的所有輸出的安全。 排序后的“ total_summe_liste”將安全地存儲為“ RM_list”,這是函數“ VaR_func”,“ CVaR_func”和“ power_func”的輸入,它們均會生成輸出,並按特定列表“ RM_VaR_list”,“ RM_CVaR_list”或“ RM_PSRM_list”。 之后,將清除“ RM_list”和“ total_summe_liste”,然后開始下一次運行。
最后,我得到了“ mega_summe_list”,“ RM_VaR_list”,“ RM_CVaR_list”和“ RM_PSRM_list”,它們將用於生成圖形和數據框。
現在,我要並行運行“重復”功能。 例如,當我要運行此函數n = 10次時,我想同時在10個CPU內核上運行它。 原因是“ copula_sim”是一個蒙特卡羅模擬,當我進行大型模擬時會花費一些時間。
我所擁有的是:
total_summe_liste = []
RM_VaR_list = []
RM_CVaR_list = []
RM_PSRM_list = []
mega_summe_list = []
def repeat():
global RM_list
global total_summe_liste
global RM_VaR_list
global RM_CVaR_list
global RM_PSRM_list
global mega_summe_list
copula_sim(runs_sim, rand_x, rand_y, mu, full_log=False)
mega_summe_list += total_summe_liste
RM_list = sorted(total_summe_liste)
VaR_func(alpha)
RM_VaR_list.append(VaR)
CVaR_func(alpha)
RM_CVaR_list.append(CVaR)
power_func(gamma)
RM_PSRM_list.append(risk)
RM_list = []
total_summe_liste = []
n = 10
for i in range(0,n):
repeat()
到目前為止,它一直在工作。
我嘗試過:
if __name__ == '__main__':
jobs = []
for i in range(0,10):
p = mp.Process(target=repeat)
jobs.append(p)
p.start()
但是,當我運行此命令時,“ mega_summe_list”為空。當我添加“ print(VaR)重復一次時,它會顯示完成后的所有10 VaR。因此,並行任務到目前為止已經可以正常工作了。
問題是什么?
出現此問題的原因是,列表mega_summe_list
在進程之間不共享。
當您在python中調用並行處理時,所有函數和變量都將導入並在不同進程中獨立運行。
因此,例如,當您啟動5個進程時,這些變量的5個不同副本將被導入並獨立運行。 因此,當您在main中訪問mega_summe_list
,它仍然為空,因為在此過程中它為空。
要啟用進程之間的同步,可以使用多處理程序包中的列表代理。 多處理管理器維護一個獨立的服務器進程,這些Python對象存放在該服務器進程中。
以下是用於創建多處理管理器列表的代碼,
from multiprocessing import Manager
mega_summe_list = Manager().List()
使用多處理時,可以使用以上代碼代替mega_summe_list = []
。
下面是一個例子
from multiprocessing.pool import Pool
from multiprocessing import Manager
def repeat_test(_):
global b, mp_list
a = [1,2,3]
b += a
mp_list += a # Multiprocessing Manager List
a = []
if __name__ == "__main__":
b = []
mp_list = Manager().list()
p = Pool(5)
p.map(repeat_test, range(5))
print("a: {0}, \n mp_list: {1}".format(b, mp_list))
輸出:
b: [],
mp_list: [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
希望這能解決您的問題。
您應該使用Multiprocessing Pool ,然后可以執行以下操作:
p = Pool(10)
p.map(repeat, range(10))
我這樣解決了這個問題:
此函數是我想以並行方式重復n次的函數:
from multiprocessing import Process
from multiprocessing import Manager
from multiprocessing.pool import Pool
def repeat(shared_list, VaR_list, CVaR_list, PSRM_list, i):
global RM_list
global total_summe_liste
copula_sim(runs_sim, rand_x, rand_y, mu, full_log=False)
shared_list += total_summe_liste
RM_list = sorted(total_summe_liste)
VaR_func(alpha)
VaR_list.append(VaR)
CVaR_func(alpha)
CVaR_list.append(CVaR)
power_func(gamma)
PSRM_list.append(risk)
RM_list = []
total_summe_liste = []
這部分管理共享列表並執行並行處理。 謝謝@ noufel13!
RM_VaR_list = []
RM_CVaR_list = []
RM_PSRM_list = []
mega_summe_list = []
if __name__ == "__main__":
with Manager() as manager:
shared_list = manager.list()
VaR_list = manager.list()
CVaR_list = manager.list()
PSRM_list = manager.list()
processes = []
for i in range(12):
p = Process(target=repeat, args=(shared_list, VaR_list, CVaR_list, PSRM_list, i)) # Passing the list
p.start()
processes.append(p)
for p in processes:
p.join()
RM_VaR_list += VaR_list
RM_CVaR_list += CVaR_list
RM_PSRM_list += PSRM_list
mega_summe_list += shared_list
RM_frame_func()
plotty_func()
謝謝!
剩下的唯一問題是我如何處理大數組? 有沒有辦法有效地做到這一點? 12個共享列表之一可以包含超過100.000.000個項目,因此mega_summe_list總共具有約1.200.000.000個項目...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.