Python concurrent.futures 多次调用导入的模块

Python concurrent.futures multiple calls to imported modules

在深入细节之前,我想提一下我已经阅读了这个 post,其中的问题看起来非常相似:

Spyder 4.0.1/Python3.7.1 64 位/Windows10

然而,采取了保护我的顶级代码的谨慎步骤似乎对我的情况不起作用。 我使用 concurrent.futuresProcessPollExecutor 来执行下面的代码。 在 pandas 之外,numpy...代码调用两个自定义模块:HAL_PROC 和 HAL_FUNC,包含 类 和执行下面循环所需的函数。

执行时,HAL_PROC.py 调用另一个生成 GUI 的模块,她或他可以在其中指定输入路径、文件名...此值或存储在变量中。

我的问题是:当我 运行 代码时,无论是在 Spyder 中还是编译成 .exe 文件时,它都会执行 main() 函数,GUI 在屏幕上生成 8 次.即使没有调用主要部分中的模块或任何相关模块,因为所有内容都存储在变量中,甚至是函数。

我确定我遗漏了有关如何正确设置多处理代码的重要细微差别,我们将不胜感激。

import pandas as pd
import numpy as np
from HAL_PROC import N_tab, N_tab_FCT, TYPE, TR, CA
from HAL_FUNC import *
import multiprocessing
from concurrent.futures import ProcessPoolExecutor


alpha = 0.05
alg_type = TYPE

if alg_type == "O":
    F = FFR_ME

elif alg_type == "NO":
    F = FFR_ME_NO        

else :
    raise TypeError("Algortithm type selected does not exist. Must be 'O' or 'NO'")


def main():

    """ Set the variables for the loop """
    futures = []
    e = ProcessPoolExecutor(8)      

    """ Loop over the different task summarized in the tab 'N_tab' during the MPO_PROC step. """
    for task in N_tab["TASK_NUMBER"]:

         """ Declare variables N, n , f based on the previous calculations """ 

         N = int(N_tab.loc[N_tab["TASK_NUMBER"] == task, "N_Task"])
         n = int(N_tab.loc[N_tab["TASK_NUMBER"] == task, "n_i"])
         f = int(N_tab.loc[N_tab["TASK_NUMBER"] == task, "F"])

         """" Implement the function using the concurrent.future module for multiprocessing. """ 

         future = e.submit(F, N, n, f, alpha)     
         futures.append(future)

    results = [ff.result() for ff in futures] 

    for i in range(len(results)):
        f = int(N_tab.loc[i, "F"])                                                
        N_tab.loc[i,"LBound"] = results[i][0][f]
        N_tab.loc[i,"UBound"] = results[i][1][f]
        N_tab.loc[i,"ME"] = (N_tab.loc[i,"UBound"] - N_tab.loc[i,"LBound"])/\
                                               (2*N_tab.loc[i,"N_Task"])
        N_tab.loc[i,"FFR"] = (N_tab.loc[i,"LBound"] + (N_tab.loc[i,"UBound"] - N_tab.loc[i,"LBound"])/2)/\
                                                N_tab.loc[i,"N_Task"]                                                

if __name__ == "__main__":
    multiprocessing.freeze_support()
    main()

经过一番挖掘,我找到了解决问题的方法,以防万一。 与我发现的很多帖子相反,用 if "__name__" == __main__ 保护我的代码是不够的。

1) 我更改为 multiprocessing 库而不是 concurrent.future,这是前者的简化版本。 (见下面的代码)。

2) 结果表明,在 Ipython 控制台中 Windows 的多处理不是很可靠 ()。解决多次调用import的问题 我在开头添加了这段代码:

import sys
sys.modules['__main__'].__file__ = 'ipython'

最后,代码看起来像这样并且工作完美,(不再有损坏的进程池或弹出多个 GUI)。

import pandas as pd
import numpy as np
import json

from HAL_PROC import N_tab, N_tab_FCT, TYPE, TR, CA
from HAL_FUNC import *
from HAL_GRAPH import Dossier_graph, Forecast_graph

from multiprocessing import Pool
import multiprocessing as mp
import matplotlib.backends.backend_pdf  

import sys
sys.modules['__main__'].__file__ = 'ipython'


""" ========================================================== """
"""                   FFR +/- ME CALCULATION                   """
""" ========================================================== """


def main():    
    with Pool() as p:
         results = p.starmap(F,zip(N,n,f,alpha))
         results_fct = p.starmap(F,zip(N_fct,n_fct,f_fct,alpha_fct))
         p.close()
         p.join()

if __name__ == "__main__":
    N_tab, N_tab_FCT = main()