You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中Multiprocessing.Value嵌套Ctypes Structure为何引发RecursionError?

多进程共享ctypes结构体触发RecursionError的解决方法

问题现象

使用multiprocessing.Value()在多进程间共享ctypes Structure时,部分结构体初始化时会触发RecursionError,报错发生在Multiprocessing内部深层逻辑,且排除了结构体大小的影响,类似小结构体可正常工作。

示例代码

from ctypes import c_float, c_bool, c_int, Structure
from multiprocessing import Value

class goodStruct(Structure):
    _pack_ = 1
    _fields_ = [
        ('connected'            ,c_bool),
        ('connected_complete'   ,c_bool)
    ]

class badStruct(Structure):
    _pack_ = 1
    _fields_ = [
        ('connected'            ,c_bool),
        ('connected_complete'   ,c_bool),
        ('power_arm'            ,c_bool),
        ('power_arm_complete'   ,c_bool),
        ('slowmove'             ,c_bool),
        ('slowmove_complete'    ,c_bool),
        ('livemove'             ,c_bool),
        ('livemove_complete'    ,c_bool),
        ('end_livemove'         ,c_bool),
        ('end_livemove_complete',c_bool),
        ('error'                ,c_int),
        ('clear_error'          ,c_bool),
        ('clear_error_complete' ,c_bool),
        ('release'              ,c_bool),
        ('release_complete'     ,c_bool),
        ('stop'                 ,c_bool),
        ('stop_complete'        ,c_bool)
    ]


a = Value(goodStruct)

b = Value(badStruct)

报错信息

Traceback (most recent call last):
  File "C:\Users\e33965\Software\z_messing around\struct_test.py", line 36, in <module>
    b = Value(badStruct)
  File "C:\Users\e33965\Miniconda3\lib\multiprocessing\context.py", line 135, in Value
    return Value(typecode_or_type, *args, lock=lock,
  File "C:\Users\e33965\Miniconda3\lib\multiprocessing\sharedctypes.py", line 82, in Value
    return synchronized(obj, lock, ctx=ctx)
  File "C:\Users\e33965\Miniconda3\lib\multiprocessing\sharedctypes.py", line 122, in synchronized
    return scls(obj, lock, ctx)
  File "C:\Users\e33965\Miniconda3\lib\multiprocessing\sharedctypes.py", line 190, in __init__
    self.release = self._lock.release
  File "<string>", line 13, in setrelease
  File "<string>", line 7, in getrelease
  File "<string>", line 7, in getrelease
  File "<string>", line 7, in getrelease
  [Previous line repeated 989 more times]
  File "<string>", line 3, in getrelease
RecursionError: maximum recursion depth exceeded while calling a Python object

解决方案

重命名结构体中与synchronized类内置方法重名的字段——你的badStruct里的release字段和synchronized实例的release(锁释放方法)重名,导致属性访问时无限递归。

修改后的结构体示例:

class badStruct(Structure):
    _pack_ = 1
    _fields_ = [
        ('connected'            ,c_bool),
        ('connected_complete'   ,c_bool),
        ('power_arm'            ,c_bool),
        ('power_arm_complete'   ,c_bool),
        ('slowmove'             ,c_bool),
        ('slowmove_complete'    ,c_bool),
        ('livemove'             ,c_bool),
        ('livemove_complete'    ,c_bool),
        ('end_livemove'         ,c_bool),
        ('end_livemove_complete',c_bool),
        ('error'                ,c_int),
        ('clear_error'          ,c_bool),
        ('clear_error_complete' ,c_bool),
        ('release_cmd'          ,c_bool),  # 重命名字段,避免冲突
        ('release_complete'     ,c_bool),
        ('stop'                 ,c_bool),
        ('stop_complete'        ,c_bool)
    ]

原因说明

multiprocessing.Value返回的是synchronized类的实例,该类自带release方法用于释放内部锁。当结构体中存在同名字段时,动态生成的属性访问器会在访问release属性时陷入循环:尝试获取结构体字段的操作会触发锁的逻辑,而锁逻辑又会访问release方法,最终导致递归深度超出限制。

内容的提问来源于stack exchange,提问作者Nicholas Masso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:02:15