Python PyInstaller生成的Windows EXE与multiprocessing.pool一起失败

Python PyInstaller生成的Windows EXE与multiprocessing.pool一起失败,python,windows,python-3.x,pyinstaller,python-multiprocessing,Python,Windows,Python 3.x,Pyinstaller,Python Multiprocessing,我使用Python的multiprocessing.Pool库以以下方式创建多个进程: def parallel_function(f): def easy_parallize(f, sequence): """ assumes f takes sequence as input, easy w/ Python's scope """ pool = Pool(processes=8) # depends on available cores

我使用Python的multiprocessing.Pool库以以下方式创建多个进程:

def parallel_function(f):
    def easy_parallize(f, sequence):
        """ assumes f takes sequence as input, easy w/ Python's scope """
        pool = Pool(processes=8)  # depends on available cores
        result = pool.map(f, sequence)  # for i in sequence: result[i] = f(i)
        cleaned = [x for x in result if x is not None]  # getting results
        cleaned = np.asarray(cleaned)
        pool.close()
        pool.join()
        return cleaned
    return partial(easy_parallize, f)
其中f是执行工作的函数,sequence是参数,有关教程,请参见

该项目正在使用PyInstaller 3.1.1打包到单个Windows EXE中。使用--onedir选项。PyInstaller创建的EXE没有问题,我能够执行程序中不使用多线程的部分

当我试图执行程序中使用上述多处理函数的部分时,我的问题就出现了。然后,程序失败并显示以下错误消息(由每个子线程反复写入):

freeze_支持来自于一个建议,其中main应该包含调用作为第一行:

if name == "__main__":
    multiprocessing.freeze_support()
类似的问题已经在中讨论过,并提到了上面链接中的解决方案,但是,A)所讨论的--onedir的解决方案似乎对我不起作用,正如您从我收到的错误消息中所看到的,b)我不知道_Popen与池绑定有何关系,因此对于--onefile,我甚至不知道如何实现类的重新定义

如果我不在main中使用multiprocessing.freeze_support(),程序的行为会有所不同,因为运行时错误不会发生,相反,我会将程序的使用说明一遍又一遍地打印到cmd中,我假设每个生成的进程都试图调用EXE,这显然不是应该发生的

不用说,程序作为.py脚本运行时没有问题

我在Windows10上使用32位的Python3.4(与Python2.7也有同样的多线程问题)


我能想到的唯一其他解决方案是重写我的解决方案,使用multiprocessing.Process而不是multiprocessing.Pool,因为似乎有一个解决方案。如果你有一个合理的低努力的方式来做我的池函数正在做的事情,我会满足的

你找到解决问题的办法了吗?我也有同样的问题,但我设法用一个简单的代码使它工作。但是,它还不能与我的完整编码(使用sklearn)一起工作。如果你能成功的话,让我知道,这可能对我也有帮助

以下是对我有用的编码:

import multiprocessing
import time

def func (param1, param2):
    print ("hello " + str (param1))
    time.sleep (param2)
    print ("Hello again " + str (param1))
    return "test "  + str (param1)

def main ():
    lParams = [("test1", 3),
               ("test2", 2),
               ("test3", 1)]
    args = []
    for param1, param2 in lParams:
        tup = (param1, param2)
        args.append (tup)

    with multiprocessing.Pool (multiprocessing.cpu_count ()) as p:
        results = [p.apply_async (func, a) for a in args]
        for r in results:
            print ("Returned " + r.get ())

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

请注意,我正在使用pyinstaller(一个目录)中的“-D”选项编译我的应用程序。

最终对我起作用的是在函数范围内导入库,并从全局命名空间中导入库。因为这是很久以前的事了,我不记得为什么了,但我记得移动库导入使我能够继续并最终完成我的项目。如果这没有帮助,而您仍然存在问题,请告诉我,我可以随时与您共享代码,以便您可以仔细查看,重点是它最终工作正常。您好@Mjellma,您能为您的问题提供答案吗?我知道你能处理这个错误。
import multiprocessing
import time

def func (param1, param2):
    print ("hello " + str (param1))
    time.sleep (param2)
    print ("Hello again " + str (param1))
    return "test "  + str (param1)

def main ():
    lParams = [("test1", 3),
               ("test2", 2),
               ("test3", 1)]
    args = []
    for param1, param2 in lParams:
        tup = (param1, param2)
        args.append (tup)

    with multiprocessing.Pool (multiprocessing.cpu_count ()) as p:
        results = [p.apply_async (func, a) for a in args]
        for r in results:
            print ("Returned " + r.get ())

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