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

解决Python类中使用Multiprocessing时的weakref pickle错误

问题:FastAPI中使用multiprocessing单例类启动多进程报pickle错误

问题背景

开发Python FastAPI应用时,使用multiprocessing库启动并行的忙碌循环进程。最初在main.py的启动阶段创建进程完全正常,后来为了让特定FastAPI端点也能控制这些进程,将进程创建逻辑移至单例类thread_utils中,供启动流程和端点调用。但移入类后,启动多个进程时触发如下错误:

报错信息

File "/home/user/.local/lib/python3.8/site-packages/starlette/routing.py", line 677, in lifespan
    async with self.lifespan_context(app) as maybe_state:
  File "/home/user/.local/lib/python3.8/site-packages/starlette/routing.py", line 566, in __aenter__
    await self._router.startup()
  File "/home/user/.local/lib/python3.8/site-packages/starlette/routing.py", line 654, in startup
    await handler()
  File "/home/user/Projects/test/test-api/api/main.py", line 127, in startup_event
    thread_utils.launch_all_threads()
  File "/home/user/Projects/test/test-api/api/core/thread_utils.py", line 66, in launch_all_threads
    p.start()
  File "/usr/lib/python3.8/multiprocessing/process.py", line 121, in start
    self._popen = self._Popen(self)
  File "/usr/lib/python3.8/multiprocessing/context.py", line 224, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "/usr/lib/python3.8/multiprocessing/context.py", line 284, in _Popen
    return Popen(process_obj)
  File "/usr/lib/python3.8/multiprocessing/popen_spawn_posix.py", line 32, in __init__
    super().__init__(process_obj)
  File "/usr/lib/python3.8/multiprocessing/popen_fork.py", line 19, in __init__
    self._launch(process_obj)
  File "/usr/lib/python3.8/multiprocessing/popen_spawn_posix.py", line 47, in _launch
    reduction.dump(process_obj, fp)
  File "/usr/lib/python3.8/multiprocessing/reduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
TypeError: cannot pickle 'weakref' object

原本在main.py中正常运行的代码,移入类后仅能启动一个进程,启动多个就会触发该TypeError。曾推测是Python进程fork机制问题,参考过CPython相关issue和multiprocessing文档的安全导入说明,但并未解决。

出错的代码示例

main.py

from .core.thread_utils import thread_utils
thread_utils = thread_utils()
...
@app.on_event("startup") # FastAPI启动事件
async def startup_event():
    # 之前在这里创建进程完全正常
    thread_utils.launch_all_threads()

core/thread_utils.py

from multiprocessing import Process
from ..core import busy_loop

class thread_utils:
    _self = None

    def __new__(cls):
        if cls._self is None:
            cls._self = super().__new__(cls)
            return cls._self

    def launch_runner_thread(self, t:int):
        busy_loop(t)

    def launch_all_threads(self):
        t_list = [1,2]
        for t in t_list:
            p = Process(target=self.launch_runner_thread, args=(t,))
            p.start()

解决方法

经@pts建议,将单例类改为无类的函数形式后问题解决,工作代码如下:

main.py

from .core.thread_utils import launch_all_threads
...
@app.on_event("startup")
async def startup_event():
    launch_all_threads()

core/thread_utils.py

from multiprocessing import Process
from ..core import busy_loop

def launch_runner_thread(t:int):
    busy_loop(t)

def launch_all_threads():
    t_list = [1,2]
    for t in t_list:
        p = Process(target=launch_runner_thread, args=(t,))
        p.start()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:52:53