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

Python异步脚本能否多端口启动守护进程?是否需用子进程?

解决Trio异步启动多个守护进程的问题

你的问题核心是同步等待单个任务导致阻塞,完全不需要用subprocess,用Trio自带的nursery就能在同一个脚本里实现多端口服务同时运行,下面是具体解决方案:

问题根源

你当前的代码中,await Daemon.new(...)会一直等到__start方法里的trio.sleep_forever()执行完毕才会继续循环,但sleep_forever永远不会结束,所以第一个守护进程启动后就卡住了,无法继续启动后续服务。

异步函数不能直接调用(会返回未执行的协程对象并报错),也不能用普通的await等待单个任务到底,需要用Trio的任务调度器来同时管理多个异步任务。

修改后的代码

import trio

class Daemon:
    def __init__(self, port):
        self.port = port
        # 假设create_server返回AbstractAsyncContextManager
        self.server = create_server()

    async def start(self):
        print(f"starting with port... {self.port}")
        # 初始化并启动服务
        async with self.server.start(port=self.port):
            print(f"server ok on port {self.port}")
            # 持续等待连接
            await trio.sleep_forever()
        print(f"exiting port {self.port}.")

async def run():
    num = 3
    # 使用nursery管理所有异步任务
    async with trio.open_nursery() as nursery:
        for i in range(num):
            daemon = Daemon(5000 + i)
            # 把每个守护进程的启动任务交给nursery,非阻塞执行
            nursery.start_soon(daemon.start)

if __name__ == "__main__":
    trio.run(run)

关键改动说明

  1. 重构Daemon类:

    • 把异步初始化改成普通的__init__(如果create_server是异步操作,可改成异步构造方法,但这里假设它同步返回上下文管理器)。
    • 把启动逻辑抽成公开的start方法,方便任务调度器调用。
  2. 使用Trio Nursery:

    • trio.open_nursery()是Trio用来管理多个异步任务的核心工具,它会自动调度所有通过start_soon提交的任务,让它们同时运行。
    • nursery.start_soon(daemon.start)不会等待任务完成,而是立即返回,所以循环可以继续创建并启动下一个守护进程。
    • Nursery会一直保持运行,直到所有任务结束(或者手动取消),正好符合你持续等待连接的需求。

补充说明

  • 你之前尝试去掉await报错,是因为异步函数调用必须通过await或者任务调度器(如start_soon)来触发执行,直接调用只会生成未执行的协程对象,Python会抛出警告/错误。
  • Trio的任务不需要你手动await单个任务,nursery会统一管理所有任务的生命周期,确保它们都能持续运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 16:44:56