python asyncio call_soon_threadsafe真的是线程安全的吗?

问题描述 投票:3回答:1

我看到一些使用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

原谅我可怜的英语。

python multithreading python-asyncio
1个回答
3
投票

根据https://bugs.python.org/issue15329#msg199368

deque的append(),appendleft(),pop(),popleft()和len(d)操作在CPython中是线程安全的。

在同一条消息中有关于Queue的信息:

那么,deque是否可以更快地替换Queue.Queue?

是的,它更快。 Queue模块本身在内部使用deque。并且通过锁定,函数间接以及诸如maxsize,join和task_done之类的附加功能,Queue会稍微减慢速度。

deque只是一个数据结构,但Queue(以及asyncio.Queue)提供了更多功能,允许更灵活的控制流程。

© www.soinside.com 2019 - 2024. All rights reserved.