挂在pool.join()

时间:2015-12-03 14:17:37

标签: python multiprocessing ipython pyzmq

当我尝试使用multiprocessing模块时,我遇到了Python冻结问题。我使用Spyder 2.3.2和Python 3.4.3(我以前遇到过特定于iPython的问题)。

我已将其减少到以下MWE:     导入多处理

def test_function(arg1=1,arg2=2):
    print("arg1 = {0}, arg2 = {1}".format(arg1,arg2))
    return None

pool = multiprocessing.Pool(processes=3)
for i in range(6):
    pool.apply_async(test_function)

pool.close()
pool.join()

目前,这应该只产生六次相同的test_function迭代。但是,虽然我可以毫不费力地输入命令,但当我发出命令pool.join()时,iPython会挂起,我必须重新启动内核。

该功能在串行完成后效果非常好(我的MWE的下一步是使用pool.apply_async(test_function,kwds=entry)

for i in range(6):
    test_function()
arg_list = [{'arg1':3,'arg2':4},{'arg1':5,'arg2':6},{'arg1':7,'arg2':8}]
for entry in arg_list:
    test_function(**entry)

我(偶尔,我无法可靠地重现它)遇到ZMQError: Address already in use的错误消息,这导致我this bug report,但在我的代码之前usort() 1}}或multiprocessing.set_start_method('spawn')似乎无法正常工作。

有人可以提供任何帮助/建议吗?如果是的话,提前致谢。

2 个答案:

答案 0 :(得分:2)

@Anarkopsykotik是正确的:你必须使用main,你可以通过将结果返回主线程来打印它。

这是一个有效的例子。

import multiprocessing
import os

def test_function(arg1=1,arg2=2):
    string="arg1 = {0}, arg2 = {1}".format(arg1,arg2) +" from process id: "+ str(os.getpid())
    return string

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=3)
    for i in range(6):
        result = pool.apply_async(test_function)
        print(result.get(timeout=1))
    pool.close()
    pool.join()

答案 1 :(得分:1)

我想到的两件事可能会引发问题。 首先,在doc中,有关于将交互式解释器与多处理模块一起使用的警告: https://docs.python.org/2/library/multiprocessing.html#using-a-pool-of-workers

  

此程序包中的功能要求子项可以导入 main 模块。这在编程指南中有所涉及,但值得在此指出。这意味着某些示例(例如Pool示例)将无法在交互式解释器中使用。

第二:您可能希望使用异步函数检索字符串,然后从主线程中显示它。我不太确定子线程是否可以访问标准输出,这可能会被锁定到主线程。