【问题标题】:Is python asyncio call_soon_threadsafe really thread-safe?python asyncio call_soon_threadsafe 真的是线程安全的吗?
【发布时间】:2017-12-16 15:02:27
【问题描述】:

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

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

    双端队列的 append()、appendleft()、pop()、popleft() 和 len(d) 操作在 CPython 中是线程安全的。

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

    那么,deque 是不是 Queue.Queue 的更快替代品?

    是的,它更快。 Queue 模块本身在内部使用双端队列。 并且通过锁、函数间接和 maxsize、join 和 task_done 等附加功能,Queue 会稍微变慢。

    deque 只是一个数据结构,但 Queue(和 asyncio.Queue 也是如此)提供了更多,允许更灵活的控制流。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-23
      相关资源
      最近更新 更多