在后台使用Python异步函数进行"fire and forget"操作

3
我试图以非阻塞的方式执行一个异步无限循环函数。目前我有以下代码:
class OpcuaClient():
    def __init__(self):
        ...
        #subscribe to changes
        loop = asyncio.get_event_loop()
        loop.create_task(self.subscribe_to_node(self.type_Nid))
        loop.create_task(self.subscribe_to_node(self.housingSerial_Nid))
        loop.run_forever()
 
        print("subprocesses started")
 
    async def subscribe_to_node(self, nodeid):
        async with Client(url=self.url) as client:
            node = client.get_node(nodeid)
            # subscribing to node
            sub = await client.create_subscription(500, self.handler)
            await sub.subscribe_data_change(node)
            # subscribe for infinte time
            while True:
                await asyncio.sleep(1)

然而,loop.run_forever() 阻塞了程序执行,导致 "subprocess started" 没有被打印出来。请注意,我想在同步构造函数中启动后台进程。我该如何实现?我也尝试了一些多处理/线程的方法,但都失败了。

2个回答

1
一旦您启动事件循环,例如使用loop_forever,它将接管控制。 "Forever"意味着直到明确停止为止。打印消息的以下语句将在循环关闭后到达,但然后所有异步操作也会停止。
如果您需要作为任务运行“后台”服务,则还需要将“前台”代码转换为异步任务或使用多线程或多进程,正如您在问题中提到的一样,但是如果不知道与后台任务的通信意图的详细信息,很难提出任何建议。

谢谢您的回答。问题是我无法使前台代码异步,因为我正在另一个构造函数中初始化类,该构造函数是gRPC服务器。理想情况下,当我构建OpcuaClient实例时,我希望生成2个订阅后台进程。那么我该如何使用线程/多进程来实现呢?我对此不太熟悉。 - Bauer Marius

1

通过结合多线程和异步任务,如@norbeq所述这里,解决了我的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接