【问题标题】:Python: exec with ProcessPoolExecutorPython:使用 ProcessPoolExecutor 执行
【发布时间】:2020-08-09 18:57:27
【问题描述】:
from concurrent.futures import ProcessPoolExecutor
import os
import time

def parInnerLoop(item):
    a = 2+item
    print(f'A. {a} Processing {os.getpid()} done on {item}\n')
    exec(open('mainWork.py').read())
    print(f'D. {a} Processing {os.getpid()} done on {item}\n')

def main():
    with ProcessPoolExecutor(max_workers=4) as executor:
        for itemNo in range(10):
            executor.submit(parInnerLoop, itemNo)
    print('done')

if __name__ == '__main__':
    main()

mainWork.py

print(f'B. {a} Processing {os.getpid()} done on {item}\n')
a = 12
print(f'C. {a} Processing {os.getpid()} done on {item}\n')

错误:

Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "D:\Program Files\Python\Python37\Lib\concurrent\futures\process.py", line 101, in _python_exit
    thread_wakeup.wakeup()
  File "D:\Program Files\Python\Python37\Lib\concurrent\futures\process.py", line 89, in wakeup
    self._writer.send_bytes(b"")
  File "D:\Program Files\Python\Python37\Lib\multiprocessing\connection.py", line 183, in send_bytes
    self._check_closed()
  File "D:\Program Files\Python\Python37\Lib\multiprocessing\connection.py", line 136, in _check_closed
    raise OSError("handle is closed")
OSError: handle is closed

问题:

  1. 错误,出现在程序末尾。
  2. 我想将mainWork.py 的所有代码作为parInnerLoop 的一部分执行,这样a 值的变化应该反映在parInnerLoopmainWork.py 中,反之亦然。我得到如下输出。 a 的值不会改变打印以 D. ... 开头的位置,我希望它是 12。

项目0的输出

A. 2 Processing 19784 done on 0
B. 2 Processing 19784 done on 0
C. 12 Processing 19784 done on 0
D. 2 Processing 19784 done on 0

发生了什么事?请帮忙。

我最终想要实现的目标:以不同的设置并行运行相同的代码,而不会相互干扰

额外:

  1. 我测试了 ProcessPoolExecutor 工作正常,如图here
  2. 我使用以下代码测试了exec(open('run.py').read()) 按预期工作:

main.py

def myFun():
    a = 1
    b = 2
    print(a)
    exec(open('run.py').read())
    #execfile("run.py")
    print(a)
    print(b)
    print(c)

def main():
    myFun()

if __name__ == '__main__':
    main()

运行.py

a = a+5
b = 10
c = 15

输出

1
6
10
15

【问题讨论】:

  • 我在 Linux 上使用 3.7.6 时遇到了同样的问题。这似乎是一个开放的错误
  • @nokada,我在 Windows 上使用 Python 3.7.8 时遇到了同样的问题。看起来像,但尚未修复。
  • 更新到 python 3.9+ 来解决这个问题

标签: python python-3.x parallel-processing concurrent.futures


【解决方案1】:

不是一个完整的答案,但似乎与

有关

感谢您的报告!经过快速调查,问题似乎是由于 concurrent.futures 模块最近发生了变化。简而言之,它们维护一个对某些服务线程(名为“QueueManagerThread”)的弱引用的字典,并在退出 Python 进程时尝试关闭该字典中的任何线程。字典通常是空的,但如果存在对线程的引用,这可能会导致尝试关闭不活动的线程。在这种情况下,会引发原始异常。

https://youtrack.jetbrains.com/issue/PY-34432

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    • 2018-04-02
    • 2019-10-28
    • 1970-01-01
    • 2016-05-25
    • 2022-10-15
    相关资源
    最近更新 更多