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

Python3.11下Windows服务启动Hypercorn报错仅Debug模式可运行

Python 3.11下Windows服务启动Hypercorn报错:set_wakeup_fd only works in main thread of the main interpreter

原本在Python 3.7环境下,运行Hypercorn的Windows服务一切正常。升级到Python 3.11后,使用sc start service_name启动服务时出现如下报错:

Traceback (most recent call last):
  File "...\service.py", line 108, in main
    run_hypercorn(app, self.host, self.port, self.shutdown_trigger)
  File "...\run.py", line 36, in run_hypercorn
    asyncio.run(serve(dispatcher, hypercorn_cfg, shutdown_trigger=shutdown_trigger.wait))
  File "asyncio\runners.py", line 189, in run
  File "asyncio\runners.py", line 59, in __enter__
  File "asyncio\runners.py", line 137, in _lazy_init
  File "asyncio\events.py", line 806, in new_event_loop
  File "asyncio\events.py", line 695, in new_event_loop
  File "asyncio\windows_events.py", line 315, in __init__
  File "asyncio\proactor_events.py", line 642, in __init__
ValueError: set_wakeup_fd only works in main thread of the main interpreter

但使用pytonservice.exe -debug service_name启动时,服务可正常运行。

相关代码

run_hypercorn函数

import asyncio
from hypercorn.config import Config as HypercornConfig
from hypercorn.asyncio import serve
from hypercorn.middleware import DispatcherMiddleware

def run_hypercorn(app, host, port, shutdown_trigger=None):
    dav = dav_app(...)

    dispatcher = DispatcherMiddleware(
        {
            '/dav': dav,
            '': app,
        }
    )

    hypercorn_cfg = HypercornConfig()
    hypercorn_cfg.bind = f'{host}:{port}'
    if shutdown_trigger is None:
        asyncio.run(serve(dispatcher, hypercorn_cfg))
    else:
        loop = asyncio.get_event_loop()  # 报错位置
        loop.run_until_complete(serve(dispatcher, hypercorn_cfg, shutdown_trigger=shutdown_trigger.wait))

Windows服务类

class AppServerSvc(win32serviceutil.ServiceFramework):
    _svc_name_ = ""
    _svc_display_name_ = ""

    def __init__(self, args):
        self.shutdown_trigger = asyncio.Event()
        self.app: FastAPI = None
        self.config: Config = None
        self.port: int = None
        self.host: str = None

    def SvcDoRun(self, *args, **kwargs):
        self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
        self.main()

    def main(self):
        from ___.app import app
        from ___.run import run_hypercorn, run_uvicorn

        self.config = Config.new('config.ini', installation_folder=self.path)
        self.app = app

        self.port = self.config.webserver.get('port', None)
        self.host = self.config.webserver.get('host', None)

        self.app.state.config = self.config

        self.ReportServiceStatus(win32service.SERVICE_RUNNING)
    
        run_hypercorn(app, self.host, self.port, self.shutdown_trigger)

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(AppServerSvc)

已尝试的操作

  • 了解到asyncio的get_event_loop()等功能曾有变更导致bug,据称3.9版本已修复,但问题仍存在
  • 尝试改用asyncio.run(serve(dispatcher, hypercorn_cfg, shutdown_trigger=shutdown_trigger.wait))调用
  • 完全移除shutdown_trigger参数,仍出现相同报错
  • 检查线程情况:两种启动方式下均有5个线程,当前线程均为MainThread

疑问

  • 无法理解常规启动服务为何会触发该错误,不知道如何调整Hypercorn的启动方式
  • 该问题是否是Python仍未修复的bug?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 17:23:12