MagicStack / MagicStack/uvloop

echoclient.py fails on recent MacOS and Linux Python releases that default to the spawn start‑method

未关闭
#735 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

主要语言
Cython
星标
11.9k
派生
615
PR 合并指标
30 天内没有已合并 PR

描述

Recent Python releases on macOS and Linux use the spawn start‑method by default for new processes.

IIRC spawn starts a brand‑new interpreter and imports the target module it relies on pickling to transport the target function.

As only module‑level objects can be pickled and run_test is defined inside the if __name__ == "__main__" block, the child process tries to unpickle and look up as an attribute of the module __mp_main__. That attribute does not exist, and the unpickler raises:

Process ForkServerProcess-2:
  File "/usr/lib/python3.14/multiprocessing/process.py", line 320, in _bootstrap
    self.run()
    ~~~~~~~~^^
  File "/usr/lib/python3.14/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.14/concurrent/futures/process.py", line 242, in _process_worker
    call_item = call_queue.get(block=True)
  File "/usr/lib/python3.14/multiprocessing/queues.py", line 120, in get
    return _ForkingPickler.loads(res)
           ~~~~~~~~~~~~~~~~~~~~~^^^^^
AttributeError: module '__mp_main__' has no attribute 'run_test'

I am not filing a pull request because there are at least three fixes, and which one is implemented depends on the project team's preferences.

The options I see that fit the file's stated minimal changes from upstream constraint:

  1. Move run_test to the module level.
  2. As this is I/O bound, change to the ThreadPoolExecutor
  3. Force the use of fork()
import multiprocessing
multiprocessing.set_start_method('fork', force=True)

All three options seem to benchmark close to each other on Linux/MacOS. Personally I lean towards the ThreadPoolExecutor option as that is my personal default for I/O bound concurrent operations.

贡献指南

这个仓库没有索引到贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 echoclient.py 开始,重点查看 main 块中的 run_test 定义及其进程池设置。根据项目的最小改动约束,审查提出的三种方案,然后使用 spawn 在某个 Python 发行版上运行客户端,以确认问题已解决且未改变其预期行为。

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
testing
Issue 类型
缺陷
难度
3/5
预计耗时
1-2 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。