我在使用 multiprocessing.Process 时遇到一些问题。简单来说,我创建了多个进程
p
,并通过调用
p.start()
来启动它们。
import multiprocessing
def _start_process(args):
# some other codes to generate some_args
q = multiprocessing.Queue()
p = multiprocessing.Process(target=some_func, args=[q, some_args])
p.start()
# retrieve result from queue, join and close the process in some other functions.
这在大多数情况下都可以正常工作,但是我在调用
start
时偶尔会遇到一个奇怪的错误:
Traceback (most recent call last):
File ".../__init__.py", line 63, in _start_process
p.start()
File ".../lib/python3.10/multiprocessing/process.py", line 120, in start
_cleanup()
File ".../lib/python3.10/multiprocessing/process.py", line 64, in _cleanup
if p._popen.poll() is not None:
AttributeError: 'NoneType' object has no attribute 'poll'
该错误并不经常发生。但是,我仍然需要解决这个问题,因为每当我运行一项大型作业时,一个未启动的进程最终会破坏最终结果。由于这种情况是随机发生的,因此我无法可靠地复制该错误。当我在主进程中使用大块内存(~20GB)并同时启动许多短进程(~40)时,这种错误似乎更频繁地发生。这不是酸洗错误,因为我只将一小部分数据分发到每个进程。我正在使用 RockyLinux 9.0 和 python 3.10。
如果有人能向我提供有关调用
p._popen
时
None
是
p.start
什么场景的线索,那就太好了。
这个错误提示在
multiprocessing.Process
对象
p
上,
p._popen
的值为
None
,导致无法调用
poll
方法。这通常意味着在创建进程时,启动子进程的底层机制失败了,而
p._popen
没有被正确设置。
以下是一些可能导致此问题的原因和建议的调试步骤:
1. 资源限制:
- 文件描述符限制: 每个进程都有一个打开文件描述符的数量限制。如果同时启动许多进程,并且每个进程都打开许多文件或套接字,则可能会达到此限制。尝试增加系统和用户级别的文件描述符限制。
- 内存限制: 提到在使用大量内存时问题更频繁地发生。尝试减少主进程的内存使用量,或者增加系统可用的内存。
2. 子进程启动失败:
-
目标函数错误:
确保
some_func
函数没有引发任何异常,并且它可以成功完成。尝试在单独的脚本中运行some_func
函数,看看是否出现任何错误。 -
参数传递错误:
检查传递给
some_func
的参数,确保它们是可序列化的并且没有错误。 - 环境问题: 尝试在一个干净的环境中运行的代码,以消除任何潜在的库冲突或环境变量问题。
3. 调试步骤:
-
打印日志:
在
_start_process
函数中添加print
语句,以查看进程创建过程中变量的值,尤其是在p.start()
之前和之后打印p._popen
的值。 -
使用
try...except
块: 将p.start()
包裹在try...except
块中,并在异常发生时打印错误信息,以获取更多关于失败原因的上下文。 - 简化代码: 尝试创建一个最小化的代码示例,仅包含重现错误所需的最少代码。这将有助于隔离问题并排除其他因素的影响。
4. 其他建议:
-
尝试使用
concurrent.futures
模块,它提供了一种更高级别的 API 来管理并发任务,并且可能更稳定。 - 升级 Python 版本: 确保使用的是最新版本的 Python,因为旧版本可能包含已修复的错误。
请尝试以上步骤来诊断和解决的问题。如果问题仍然存在,请提供更多上下文信息,例如的代码示例、操作系统版本和 Python 版本,以便我提供更具体的帮助。
标签:python,python-multiprocessing From: 78786243