python asyncio call_soon_threadsafe 真的是线程安全的吗?
Is python asyncio call_soon_threadsafe really thread-safe?
我看到一些代码使用 asyncio
作为异步任务队列。可能喜欢关注
async def _send_email(address):
pass
def send_email(address):
task = asyncio.tasks.ensure_future(_send_email(address))
task.add_done_callback(callback)
def init_worker(loop):
asyncio.set_event_loop(loop)
loop.run_forever()
@app.route("/notify")
def do_jobs():
# some code
loop.call_soon_threadsafe(send_email, address)
loop = asyncio.new_event_loop()
worker = threading.Thread(target=init_worker, args=(loop,))
worker.setDaemon(True)
worker.start()
app.run()
我阅读了 call_soon_threadsafe
的实现。它会将任务附加到 loop._ready
,代码 here.
self._ready.append(handle)
但是当子线程正在执行_run_once
,并从loop._ready
弹出任务时,代码here.
handle = self._ready.popleft()
我不确定竞争条件是否存在。如果不存在,什么情况下应该使用queue.Queue
?
请原谅我糟糕的英语。
根据https://bugs.python.org/issue15329#msg199368:
The deque's append(), appendleft(), pop(), popleft(), and len(d) operations are thread-safe in CPython.
并且在同一条消息中有关于 Queue 的信息:
So, is deque a faster replacement for Queue.Queue or not?
是的,它更快。 Queue 模块本身在内部使用 deque。
Queue 通过锁、函数间接和附加功能(如 maxsize、join 和 task_done.
减慢了一点速度
deque
只是一种数据结构,但队列(以及 asyncio.Queue)提供的更多,允许更灵活的控制流。
我看到一些代码使用 asyncio
作为异步任务队列。可能喜欢关注
async def _send_email(address):
pass
def send_email(address):
task = asyncio.tasks.ensure_future(_send_email(address))
task.add_done_callback(callback)
def init_worker(loop):
asyncio.set_event_loop(loop)
loop.run_forever()
@app.route("/notify")
def do_jobs():
# some code
loop.call_soon_threadsafe(send_email, address)
loop = asyncio.new_event_loop()
worker = threading.Thread(target=init_worker, args=(loop,))
worker.setDaemon(True)
worker.start()
app.run()
我阅读了 call_soon_threadsafe
的实现。它会将任务附加到 loop._ready
,代码 here.
self._ready.append(handle)
但是当子线程正在执行_run_once
,并从loop._ready
弹出任务时,代码here.
handle = self._ready.popleft()
我不确定竞争条件是否存在。如果不存在,什么情况下应该使用queue.Queue
?
请原谅我糟糕的英语。
根据https://bugs.python.org/issue15329#msg199368:
The deque's append(), appendleft(), pop(), popleft(), and len(d) operations are thread-safe in CPython.
并且在同一条消息中有关于 Queue 的信息:
So, is deque a faster replacement for Queue.Queue or not?
是的,它更快。 Queue 模块本身在内部使用 deque。 Queue 通过锁、函数间接和附加功能(如 maxsize、join 和 task_done.
减慢了一点速度
deque
只是一种数据结构,但队列(以及 asyncio.Queue)提供的更多,允许更灵活的控制流。