【发布时间】:2019-04-06 00:24:31
【问题描述】:
我有两个共享某些状态的 Python 线程,A 和 B。在某一时刻,A 提交了一个回调,由B 在其循环中运行,类似于:
# This line is executed by A
loop.call_soon_threadsafe(callback)
在此之后我想继续做其他事情,但我想确保callback 在这样做之前已经由B 运行。有没有办法(除了标准线程同步原语)让A等待回调完成?我知道call_soon_threadsafe返回一个可以取消任务的asyncio.Handle对象,但是我不确定这是否可以用于等待(我对asyncio还是不太了解)。
在这种情况下,此回调调用loop.close() 并取消剩余的任务,然后在B 中,在loop.run_forever() 之后有一个loop.close()。因此,对于这个用例,特别是一种线程安全机制,它允许我从A 知道循环何时有效关闭也对我有用 - 再次,不涉及互斥体/条件变量/等。
我知道asyncio 并不是线程安全的,只有极少数例外,但我想知道是否提供了一种方便的方法来实现这一点。
这是我的意思的一个非常小的 sn-p,以防万一。
import asyncio
import threading
import time
def thread_A():
print('Thread A')
loop = asyncio.new_event_loop()
threading.Thread(target=thread_B, args=(loop,)).start()
time.sleep(1)
handle = loop.call_soon_threadsafe(callback, loop)
# How do I wait for the callback to complete before continuing?
print('Thread A out')
def thread_B(loop):
print('Thread B')
asyncio.set_event_loop(loop)
loop.run_forever()
loop.close()
print('Thread B out')
def callback(loop):
print('Stopping loop')
loop.stop()
thread_A()
我已经用asyncio.run_coroutine_threadsafe 尝试过这种变体,但它不起作用,而是线程A 永远挂起。不知道我做错了什么还是因为我正在停止循环。
import asyncio
import threading
import time
def thread_A():
global future
print('Thread A')
loop = asyncio.new_event_loop()
threading.Thread(target=thread_B, args=(loop,)).start()
time.sleep(1)
future = asyncio.run_coroutine_threadsafe(callback(loop), loop)
future.result() # Hangs here
print('Thread A out')
def thread_B(loop):
print('Thread B')
asyncio.set_event_loop(loop)
loop.run_forever()
loop.close()
print('Thread B out')
async def callback(loop):
print('Stopping loop')
loop.stop()
thread_A()
【问题讨论】:
-
@jdv:这些都没有使用异步。
-
如果您使用线程,您是否实际上也使用
asyncio来运行任务?还是您只使用loop.call_soon_threadsafe(callback)来处理某种与线程相关的任务?loop.call_soon_threadsafe(callback)实际上只意味着其他线程向asyncio-loop-managed 代码发送信号。 -
@jdv 谢谢,但这些不适用于多线程代码。
标签: python python-asyncio