Han*_*agi 6 python multithreading python-asyncio
我看到了一些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()
Run Code Online (Sandbox Code Playgroud)
我阅读了call_soon_threadsafe. 它将任务附加到这里loop._ready的代码。
self._ready.append(handle)
Run Code Online (Sandbox Code Playgroud)
但是当子线程正在执行_run_once,并从中弹出任务时loop._ready,代码在这里。
handle = self._ready.popleft()
Run Code Online (Sandbox Code Playgroud)
我不确定竞争条件是否存在。如果不存在,在什么情况下应该使用queue.Queue?
原谅我可怜的英语。
根据https://bugs.python.org/issue15329#msg199368:
deque 的 append()、appendleft()、pop()、popleft() 和 len(d) 操作在 CPython 中是线程安全的。
在同一条消息中还有关于 Queue 的信息:
那么,双端队列是否是 Queue.Queue 的更快替代品?
是的,它更快。Queue 模块本身在内部使用 deque。队列通过锁、函数间接和其他特性(如 maxsize、join 和 task_done)稍微减慢了速度。
deque 只是一个数据结构,但 Queue(以及 asyncio.Queue)提供了更多,允许更灵活的控制流。