【问题标题】:How to implement multi-processing into a python module?如何在 python 模块中实现多处理?
【发布时间】:2021-03-15 17:13:44
【问题描述】:

我想在我用 python 编写的模拟中实现多处理。模拟非常广泛,为了清理代码,我创建了许多模块。

其中一个模块现在应该进行一些数字运算。因此,我想实现多处理。但是,我总是会遇到一个问题,因为我无法在模块中使用 if __name__ == "__main__" 保护

我可以通过运行以下命令重现错误:

# filename: test_mp_module.py

import concurrent.futures

def test_fct(arg):
    return arg

class TestMpModule():
    def __init__(self):
        pass
    
    def do(arg):
        para = [1,2,3]
        with concurrent.futures.ProcessPoolExecutor() as executor:
            results = executor.map(test_fct, para)
            
            for result in results:
                print(result)            

# filename: main.py

from test_mp_module import TestMpModule
                
test = TestMpModule()
test.do()

异常显示状态:

runfile('C:/XXX/test_mp.py', wdir='C:/XXX')
Reloaded modules: test_mp_module
Traceback (most recent call last):

  File "C:\XXX\test_mp.py", line 17, in <module>
    test.do()

  File "C:\XXX\test_mp_module.py", line 22, in do
    for result in results:

  File "C:\YYY\Anaconda3\lib\concurrent\futures\process.py", line 484, in _chain_from_iterable_of_lists
    for element in iterable:

  File "C:\YYY\Anaconda3\lib\concurrent\futures\_base.py", line 611, in result_iterator
    yield fs.pop().result()

  File "C:\YYY\Anaconda3\lib\concurrent\futures\_base.py", line 439, in result
    return self.__get_result()

  File "C:\YYY\Anaconda3\lib\concurrent\futures\_base.py", line 388, in __get_result
    raise self._exception

BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.

我使用的是 Python 3.8.3,通常在 Spyder 中执行我的代码并运行 Windows 机器。

如何调整我的代码以在模块中利用多处理?首先这是否可能 - 我发现了非常矛盾的陈述?

感谢您的帮助,干杯。

【问题讨论】:

  • 并行处理实际上取决于您的代码、它的作用以及它的作用方式。你的代码可以异步运行吗?你试过 python-multiprocessing 模块吗?
  • 可以。基本上解决了相同的最小化问题。在这个最小化问题中,需要解决一个积分问题。这需要进行 N 次,每次选择不同的参数。接下来将尝试多处理模块。
  • 我会说试试 Corey Schafer 的视频,很好很简单。

标签: python python-3.x python-multiprocessing python-module concurrent.futures


【解决方案1】:

为你的文件“main.py”试试这个:

if __name__ == '__main__':
     test = TestMpModule()
     test.do()

对于多处理部分,我推荐使用多处理包。下面是一个关于如何使用它的小例子:

import multiprocessing


def my_func(i):
    return i


if __name__ == '__main__':
    with multiprocessing.Pool(multiprocessing.cpu_count()) as p:
        outputs = p.starmap(my_func, [(i, ) for i in range(5)])

    print(outputs)  # > [0, 1, 2, 3, 4]

【讨论】:

  • 感谢您的快速回复。遗憾的是,此更改导致相同的 BrokenProcessPool 错误
  • 我也尝试了第二个示例代码。代码无休止地运行。如果有帮助,我将阅读多处理模块并提供反馈 Ö=
【解决方案2】:

我找到了一个解决方案,但不确定它是否被认为是漂亮的。 name_guard 需要带入模块如下:

# filename: test_mp_module.py

import concurrent.futures

def test_fct(i):
    return i
    
class TestMpModule():
    def __init__(self):
        pass
                
    def do(self, name_guard):
        para = [1, 2, 3]
        if name_guard == 'parent_module_name': # check parent module name here
            with concurrent.futures.ProcessPoolExecutor() as executor:
                results = executor.map(test_fct, para)
                
                for result in results:
                    print(result)   

from test_mp_module import TestMpModule
            
if __name__ == "__main__":
    name_guard = "parent_module_name" # insert __name__ here
    test = TestMpModule()
    test.do(name_guard)

现在工作正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-15
    • 1970-01-01
    • 2022-07-04
    • 2011-04-04
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多