簡體   English   中英

如何在Python中為線程設置asyncio事件循環?

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

我正在嘗試創建兩個線程,每個線程都有自己的asyncio事件循環。

我嘗試了以下代碼,但它似乎不起作用:

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 web框架的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需求提供服務。 畢竟,能夠在單個事件循環中托管大量任務是asyncio的優勢之一。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM