python - Python 中的 ProcessPoolExecutor 和 Lock

标签 python concurrency locking multiprocessing pool

我正在尝试将 concurrent.futures.ProcessPoolExecutor 与锁结合使用,但出现运行时错误。 (如果相关的话,我正在 Windows 上工作)

这是我的代码:

import multiprocessing
from concurrent.futures import ProcessPoolExecutor

import time


def f(i, lock):
    with lock:
        print(i, 'hello')
        time.sleep(1)
        print(i, 'world')


def main():
    lock = multiprocessing.Lock()
    pool = ProcessPoolExecutor()
    futures = [pool.submit(f, num, lock) for num in range(3)]
    for future in futures:
        future.result()


if __name__ == '__main__':
    main()

这是我得到的错误:

    Traceback (most recent call last):
  File "F:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\Lib\multiprocessing\queues.py", line 242, in _feed
    obj = ForkingPickler.dumps(obj)
  File "F:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\Lib\multiprocessing\reduction.py", line 50, in dumps
    cls(buf, protocol).dump(obj)
  File "F:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\Lib\multiprocessing\synchronize.py", line 102, in __getstate__
    context.assert_spawning(self)
  File "F:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\Lib\multiprocessing\context.py", line 347, in assert_spawning
    ' through inheritance' % type(obj).__name__
RuntimeError: Lock objects should only be shared between processes through inheritance

奇怪的是,如果我用 multiprocessing.Process 编写相同的代码,一切正常:

import multiprocessing

import time


def f(i, lock):
    with lock:
        print(i, 'hello')
        time.sleep(1)
        print(i, 'world')


def main():
    lock = multiprocessing.Lock()
    processes = [multiprocessing.Process(target=f, args=(i, lock)) for i in range(3)]
    for process in processes:
        process.start()
    for process in processes:
        process.join()



if __name__ == '__main__':
    main()

这有效,我得到:

1 hello
1 world
0 hello
0 world
2 hello
2 world

最佳答案

您需要使用 Manager 并使用 Manager.Lock() 代替:

import multiprocessing
from concurrent.futures import ProcessPoolExecutor

import time

def f(i, lock):
    with lock:
        print(i, 'hello')
        time.sleep(1)
        print(i, 'world')

def main():
    pool = ProcessPoolExecutor()
    m = multiprocessing.Manager()
    lock = m.Lock()
    futures = [pool.submit(f, num, lock) for num in range(3)]
    for future in futures:
        future.result()


if __name__ == '__main__':
    main()

结果:

% python locks.py
0 hello
0 world
1 hello
1 world
2 hello
2 world

关于python - Python 中的 ProcessPoolExecutor 和 Lock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35394373/

相关文章:

java - 为什么我的 Bamboo 构建被 Java 子进程阻止?

python - 我什么时候应该使用 'path' 而不是 're_path' ?

python - 获取完整的unicode句子

Python OpenSSL 生成公钥和私钥对

performance - 衡量应用程序性能的技术

java - 尽管对象被锁定,但非同步方法仍然可以访问,为什么?

java - MySQL不等待返回物理锁错误的方法

python - 如何腌制或存储 Jupyter (IPython) 笔记本 session 以供以后使用

java - 关于阻塞同步集合

java - 在线程之间共享对象对性能有何影响?