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

导入Sanic程序至其他程序时触发‘context has already been set’错误求助

解决Sanic启动时的RuntimeError: context has already been set问题

环境信息

  • Python版本:3.10
  • Sanic-Cors版本:2.2.0
  • Sanic版本:24.6.0
  • 操作系统:Windows 11

问题现象

直接运行api.py无任何错误,但运行main.py调用启动函数时触发RuntimeError,错误日志如下:

Main  2024-08-15 21:58:44 +0800 INFO: Sanic v24.6.0
Main  2024-08-15 21:58:44 +0800 INFO: Goin' Fast @ http://127.0.0.1:5050
Main  2024-08-15 21:58:44 +0800 INFO: app: ip
Main  2024-08-15 21:58:44 +0800 INFO: mode: production, single worker
Main  2024-08-15 21:58:44 +0800 INFO: server: sanic, HTTP/1.1
Main  2024-08-15 21:58:44 +0800 INFO: python: 3.12.4
Main  2024-08-15 21:58:44 +0800 INFO: platform: Windows-11-10.0.22631-SP0
Main  2024-08-15 21:58:44 +0800 INFO: packages: sanic-routing==23.12.0
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "xxx\Python\Python312\Lib\multiprocessing\spawn.py", line 122, in spawn_main
    exitcode = _main(fd, parent_sentinel)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "xxx\Python\Python312\Lib\multiprocessing\spawn.py", line 131, in _main
    prepare(preparation_data)
  File "xxx\Python\Python312\Lib\multiprocessing\spawn.py", line 246, in prepare
    _fixup_main_from_path(data['init_main_from_path'])
  File "xxx \Python\Python312\Lib\multiprocessing\spawn.py", line 297, in _fixup_main_from_path
    main_content = runpy.run_path(main_path,
                   ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen runpy>", line 286, in run_path
  File "<frozen runpy>", line 98, in _run_module_code
  File "<frozen runpy>", line 88, in _run_code
  File "xxx\test\main.py", line 3, in <module>
    api.start_server()
  File "xxx\test\api.py", line 16, in start_server
    app.run(host="127.0.0.1", port=5050)
  File "xxx\Python\Python312\Lib\site-packages\sanic\mixins\startup.py", line 291, in run
    serve(primary=self)  # type: ignore
    ^^^^^^^^^^^^^^^^^^^
  File "xxx\Python\Python312\Lib\site-packages\sanic\mixins\startup.py", line 1003, in serve
    cls._set_startup_method()
  File "xxx\Python\Python312\Lib\site-packages\sanic\mixins\startup.py", line 932, in _set_startup_method
    set_start_method(method, force=cls.test_mode)
  File "xxx\Python\Python312\Lib\multiprocessing\context.py", line 247, in set_start_method
    raise RuntimeError('context has already been set')
RuntimeError: context has already been set

相关代码

api.py

# api.py
from sanic import Sanic, json
from sanic_cors import CORS

app = Sanic("ip")
CORS(app)


@app.route("/get_proxy")
async def ip_api(request):
    ip = "XXXXXX"
    return json({"ip": ip})


def start_server():
    app.run(host="127.0.0.1", port=5050)


if __name__ == '__main__':
    start_server()

main.py

# main.py
import api

api.start_server()

解决方案

原因分析

Windows系统下Sanic默认使用spawn方式启动子进程,当通过main.py导入api模块时,主模块(main.py)会被子进程重新导入执行,导致多进程上下文被重复设置,触发RuntimeError。

解决方法

方法1:修改main.py,将启动代码放入模块主入口块

修改后的main.py:

# main.py
import api

if __name__ == '__main__':
    api.start_server()

这种方式符合Python多进程编程规范,能避免子进程重复执行启动逻辑,从根源上解决上下文重复设置的问题。

方法2:指定Sanic以单进程模式启动

修改api.py中的start_server函数,显式指定workers=1:

def start_server():
    app.run(host="127.0.0.1", port=5050, workers=1)

单进程模式下Sanic不会创建子进程,也就不会触发多进程上下文冲突,但这种方式会限制服务的并发能力,仅适合测试场景或低并发需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 15:24:50