如果从函数内部执行,带有“apply_async”的多处理池不会执行任何操作

Del*_*gan 2 python asynchronous multiprocessing python-3.x python-multiprocessing

我正在尝试使用该multiprocessing模块,更具体地说是该Pool.apply_async()功能。

这段代码运行良好:

import multiprocessing

def do():
    print("Foobar", flush=True)

with multiprocessing.Pool(1) as pool:
    for i in range(2):
        pool.apply_async(do)

    pool.close()
    pool.join()
Run Code Online (Sandbox Code Playgroud)

"Foobar"字符串被打印两次。

但是,如果我将此代码放入函数中然后调用该函数,则不会发生任何情况。没有错误也没有"Foobar",程序静静地结束。

import multiprocessing

def test():

    def do():
        print("Foobar", flush=True)

    with multiprocessing.Pool(1) as pool:
        for i in range(5):
            pool.apply_async(do)

        pool.close()
        pool.join()

test()
Run Code Online (Sandbox Code Playgroud)

为什么?我在 Linux 上使用 Python 3.7.3。

nox*_*fox 5

为了检索您的计算结果,请对您的代码进行以下更改。

import multiprocessing

def test():

    def do():
        print("Foobar", flush=True)

    with multiprocessing.Pool(1) as pool:
        for i in range(5):
            result = pool.apply_async(do)

            result.get()

        pool.close()
        pool.join()

test()
Run Code Online (Sandbox Code Playgroud)

你会看到“什么也没发生”的原因。

Traceback (most recent call last):
  File "/tmp/test.py", line 17, in <module>
    test()
  File "/tmp/test.py", line 12, in test
    result.get()
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 608, in get
    raise self._value
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 385, in _handle_tasks
    put(task)
  File "/usr/lib/python3.5/multiprocessing/connection.py", line 206, in send
    self._send_bytes(ForkingPickler.dumps(obj))
  File "/usr/lib/python3.5/multiprocessing/reduction.py", line 50, in dumps
    cls(buf, protocol).dump(obj)
AttributeError: Can't pickle local object 'test.<locals>.do'    
Run Code Online (Sandbox Code Playgroud)

Pythonmultiprocessing.Pool依靠pickle协议来序列化要发送到其他进程的数据。该pickle协议只能序列化顶级函数,而不能序列化嵌套函数。

要查看哪些可以腌制,哪些不能腌制,请查看文档

  • 由于您没有声明结果,它只会忽略它。原因可能是您想要异步执行某些操作,无论它是否成功。您还可以检查 `concurrent.futures` 模块,它具有类似但更清晰的 API。 (2认同)