简体   繁体   English

如何在Python中为线程设置asyncio事件循环?

[英]How do I set the asyncio event loop for a thread in Python?

I'm trying to create two threads that each have their own asyncio event loop. 我正在尝试创建两个线程,每个线程都有自己的asyncio事件循环。

I've tried the following code but it doesn't seem to work: 我尝试了以下代码,但它似乎不起作用:

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()

My use case is calling Tornado web framework's websocket_connect async function. 我的用例是调用Tornado web框架的websocket_connect异步函数。

Your threads are queuing callbacks in their respective event loops, but they exit before actually running the event loop, so the callbacks never get executed. 您的线程在各自的事件循环中排队回调,但它们在实际运行事件循环之前退出,因此回调永远不会被执行。 Also, you don't need call_soon_threadsafe , since you are invoking the callback from the same thread the event loop is (or, rather, will be) running on. 此外,您不需要call_soon_threadsafe ,因为您正在从同一个线程调用事件循环(或者更确切地说,将要运行)。

This code prints the expected output: 此代码打印预期输出:

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()

A more typical use case for call_soon_threadsafe , and more in line with what you might have had in mind, is to submit a callback (or a coroutine using asyncio.run_coroutine_threadsafe ) to an event loop running in another thread. call_soon_threadsafe一个更典型的用例,更符合您的想法,是将回调(或使用asyncio.run_coroutine_threadsafe的协程)提交给在另一个线程中运行的事件循环。 Here is an example: 这是一个例子:

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)

In that case it is rarely needed to have more than one event loop thread - you'd typically create only one, and allow that thread to service all your asyncio needs. 在这种情况下,很少需要有多个事件循环线程 - 您通常只创建一个,并允许该线程为您的所有asyncio需求提供服务。 After all, being able to host a large number of tasks in a single event loop is one of the strong points of asyncio. 毕竟,能够在单个事件循环中托管大量任务是asyncio的优势之一。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将龙卷风 ioloop 设置为 asyncio event_loop? - How do I set the tornado ioloop to an asyncio event_loop? 如何在 Python asyncio 事件循环中手动启动和停止运行阻塞代码的线程? - How to manually start and stop a thread running blocking code within a Python asyncio event loop? 如何学习如何实现自定义Python asyncio事件循环? - How can I learn how to implement a custom Python asyncio event loop? 如何将 asyncio 任务添加到 pyqt5 事件循环中,以便它运行并避免从未等待的错误? - How do I add asyncio task to pyqt5 event loop so that it runs and avoids the never awaited error? 我是否需要跟踪 asyncio 事件循环,或者我可以在需要时调用 asyncio.get_event_loop 吗? - Do I need to keep track of the asyncio event loop, or can I just call asyncio.get_event_loop when it is needed? Python asyncio - 如何创建任务列表并在事件循环中使用它? - Python asyncio - How to create task list and use it in the event loop? new_event_loop 如何在 asyncio python3 中工作 - how new_event_loop work in asyncio python3 当用户单击 tkinter 根 window 关闭框时,如何从 asyncio 事件循环 run_forever() 干净地退出我的 python3 应用程序? - How do I exit my python3 application cleanly from asyncio event loop run_forever() when user clicks tkinter root window close box? 如何测量异步事件循环的长度? - How can I measure the length of an asyncio event loop? Asyncio 设置事件循环冻结 - Asyncio set event loop make freeze
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM