我想知道在一个线程中创建异步事件循环并在另一个线程中运行该循环是否安全,同时能够从运行事件循环的线程外部取消它。我想在线程中运行异步函数,同时还能够从线程外部取消它
这是我当前使用的代码,我想知道这是否是正确的方法,或者是否有更简单/更好的方法来做到这一点
import asyncio
from concurrent.futures import ThreadPoolExecutor, CancelledError
import time
pool = ThreadPoolExecutor()
loop = asyncio.new_event_loop()
def start_event_loop(loop):
asyncio.set_event_loop(loop) # is this necessary?
loop.run_forever()
pool.submit(start_event_loop, loop)
async def long_task():
try:
while True:
print("Running...")
await asyncio.sleep(1)
except asyncio.CancelledError:
print("Task was cancelled")
future = asyncio.run_coroutine_threadsafe(long_task(), loop)
time.sleep(5)
loop.call_soon_threadsafe(future.cancel)
try:
future.result()
except CancelledError:
time.sleep(1)
print("Future was cancelled")
loop.call_soon_threadsafe(loop.stop) # can i reuse the loop?
while loop.is_running():
print("Wating for loop to stop...")
time.sleep(0.1)
loop.close() # is this necessary?
print("Loop stopped")
我还想问一些额外的问题,那就是
有必要使用asyncio.set_event_loop吗?它们都产生相同的输出
停止事件循环后是否可以重用事件循环,或者我应该在停止循环后每次创建一个新循环。
用完后是否需要关闭循环。
更简单的方法:
import asyncio
import threading
import time
def start_event_loop(loop):
asyncio.set_event_loop(loop)
loop.run_forever()
async def long_task():
try:
while True:
print("Running...")
await asyncio.sleep(1)
except asyncio.CancelledError:
print("Task cancelled")
# An event loop as a separate thread
loop = asyncio.new_event_loop()
thread = threading.Thread(target=start_event_loop, args=(loop,), daemon=True)
thread.start()
# Schedule task in event loop
future = asyncio.run_coroutine_threadsafe(long_task(), loop)
# Simulate some work & cancel after 5 seconds
time.sleep(5)
loop.call_soon_threadsafe(future.cancel)
try:
future.result() # Wait for task to finish & check for exceptions
except asyncio.CancelledError:
print("Future cancelled")
# Stop & close loop
loop.call_soon_threadsafe(loop.stop)
thread.join() # Wait for thread to exit
loop.close()
print("Loop stopped")
asyncio.get_event_loop()
行可以跳过。
使用
loop.stop
停止循环后,重新使用它是不安全的。您可以使用asyncio.new_event_loop
创建新循环。
是的,需要关闭循环才能正确释放资源。