gpt4 book ai didi

python - 如何在 Python 中为线程设置异步事件循环?

转载 作者:太空狗 更新时间:2023-10-29 22:28:34 25 4
gpt4 key购买 nike

我正在尝试创建两个线程,每个线程都有自己的异步事件循环。

我试过下面的代码,但它似乎不起作用:

import asyncio
from threading import Thread

def hello(thread_name):
print('hello from thread {}!'.format(thread_name))

event_loop_a = asyncio.new_event_loop()
event_loop_b = asyncio.new_event_loop()

def callback_a():
asyncio.set_event_loop(event_loop_a)
asyncio.get_event_loop().call_soon_threadsafe(lambda: hello('a'))

def callback_b():
asyncio.set_event_loop(event_loop_b)
asyncio.get_event_loop().call_soon_threadsafe(lambda: hello('b'))

thread_a = Thread(target=callback_a, daemon=True)
thread_b = Thread(target=callback_b, daemon=True)
thread_a.start()
thread_b.start()

我的用例是调用 Tornado 网络框架的 websocket_connect 异步函数。

最佳答案

您的线程在各自的事件循环中排队回调,但它们在实际运行事件循环之前退出,因此回调永远不会执行。此外,您不需要 call_soon_threadsafe ,因为您正在从事件循环正在(或者更确切地说,将要)运行的同一线程调用回调。

此代码打印预期的输出:

import asyncio
from threading import Thread

def hello(thread_name):
print('hello from thread {}!'.format(thread_name))

event_loop_a = asyncio.new_event_loop()
event_loop_b = asyncio.new_event_loop()

def callback_a():
asyncio.set_event_loop(event_loop_a)
asyncio.get_event_loop().call_soon(lambda: hello('a'))
event_loop_a.run_forever()

def callback_b():
asyncio.set_event_loop(event_loop_b)
asyncio.get_event_loop().call_soon(lambda: hello('b'))
event_loop_b.run_forever()

thread_a = Thread(target=callback_a, daemon=True)
thread_b = Thread(target=callback_b, daemon=True)
thread_a.start()
thread_b.start()

call_soon_threadsafe 的一个更典型的用例,也更符合您的想法,是向运行的事件循环提交回调(或使用 asyncio.run_coroutine_threadsafe 的协程)在另一个线程中。这是一个例子:

import asyncio, threading

def hello(thread_name):
print('hello from thread {}!'.format(thread_name))

event_loop_a = asyncio.new_event_loop()
event_loop_b = asyncio.new_event_loop()

def run_loop(loop):
asyncio.set_event_loop(loop)
loop.run_forever()

threading.Thread(target=lambda: run_loop(event_loop_a)).start()
threading.Thread(target=lambda: run_loop(event_loop_b)).start()

event_loop_a.call_soon_threadsafe(lambda: hello('a'))
event_loop_b.call_soon_threadsafe(lambda: hello('b'))

event_loop_a.call_soon_threadsafe(event_loop_a.stop)
event_loop_b.call_soon_threadsafe(event_loop_b.stop)

在那种情况下,很少需要有多个事件循环线程——您通常只创建一个,并允许该线程满足您所有的异步需求。毕竟,能够在单个事件循环中承载大量任务是 asyncio 的强项之一。

关于python - 如何在 Python 中为线程设置异步事件循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52298922/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com