我可以使用 python 脚本作为具有异步库的守护进程运行还是需要使用子进程?

问题描述 投票:0回答:1

我需要用 python 进行快速实验。 但是,我遇到了异步问题。我对 python 异步编程不太熟悉,所以请耐心等待。

我想要的是运行一个脚本,在不同的端口启动不同的守护进程,然后等待与其建立连接。

我基本上使用了下面的代码(它不会运行,因为我想简化问题,但它应该足以说明问题。如果没有,请告诉我)。

我遇到的问题是这段代码(对于专家来说可能是显而易见的)在第一个

sleep_forever
处停止。换句话说,只有一个守护进程启动。

这可以通过同一个脚本完成吗?或者我是否需要子流程(或完全其他的东西)来启动? 我尝试从

await
中删除
self.__start()
,但这会导致错误提示
__start() was not awaited
。我的想法是,那么异步函数确实不会被等待,脚本将继续,而网络内容将被启动,然后它会等待。看起来好像不是这样的。我也尝试过启动任务,但是任务也需要等待?

import trio

class Daemon:
    port: int

    @classmethod
    async def new(cls, port):
        self = cls()
        self.port = port
        #assume this to return an `AbstractAsyncContextManager`
        self.server = create_server() `
        await self.__start()

    async def __start(self):
        print("starting with port...".format(port=self.port))
        # init network socket
        async with self.server.start(port=self.port), trio.open_nursery() as nursery:
            #setup network objects
            print("server ok")
            # ->> WAIT FOR INCOMING Connections 
            await trio.sleep_forever()

        print("exiting.")


async def run():
    d_list = []
    num = 3
    for i in range(num):
        d = await Daemon.new(5000+i)
        d_list.append(d)

if __name__ == "__main__":
    trio.run(run)
python asynchronous async-await daemon
1个回答
0
投票

您编写的是一个完全没有并发性的单线程程序。它将依次创建每个守护进程并等待该守护进程完成,然后再继续循环的下一次迭代。这根本不是你想要的。

需要使用asyncio提供并发的功能。这个功能是

Task
。任务将继续执行,直到找到无法立即完成的
await
语句。例如
sleep()
或等待套接字连接。

保留对尚未完成的任务的引用至关重要。如果不这样做可能(将)意味着任务将无法完成。由于您已经在使用

trio
,请使用它的托儿所来为您处理。

在程序中使用任务是一个简单的切换。

async def run():
    num = 3
    async with trio.open_nursery() as nursery:
        for i in range(num):
            nursery.start_soon(Daemon.new, 5000+i)

    print('all tasks in the nursery will have stopped after the with block')
    # however, as your daemons never return, this print statement is never executed
© www.soinside.com 2019 - 2024. All rights reserved.