簡體   English   中英

Python並行運行功能

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM