【问题标题】:Python3 Asyncio shared resources between concurrent tasksPython3 Asyncio 在并发任务之间共享资源
【发布时间】:2016-08-05 11:20:10
【问题描述】:

我有一个用 Python3.5 编写的网络应用程序,它利用 pythons Asyncio 同时处理每个传入连接。

在每个并发连接上,我想将连接的客户端数据存储在一个列表中。我担心如果两个客户端同时连接(这是可能的),那么两个任务都会尝试同时写入列表,这肯定会引发问题。我将如何解决这个问题?

【问题讨论】:

  • 如果您使用 HTTP,您应该使用 aiohttp,它 (AFAIK) 会为您处理所有这些。

标签: python python-3.x concurrency python-asyncio shared-resource


【解决方案1】:

asyncio 仅在 yield 点await 表达式)上进行上下文切换,因此两个并行任务不会在相同时间执行。

但如果仍然可能出现竞争条件(这取决于具体的代码结构),您可以使用asyncio synchronization primitivesqueues

【讨论】:

  • 每个客户端连接都由一个单独的任务处理。在每个任务中,当客户端被处理时,数据被附加到一个全局列表中。 task = asyncio.Task(self._handle_client(client_reader, client_writer)) self.clients[task] = (client_reader, client_writer)_handle_client 内的列表被附加到。如果两个客户端同时连接,这会导致问题吗?
  • 不,很安全。
【解决方案2】:

您的问题中缺少很多信息。

  • 您的应用程序是否线程化?如果是,那么您必须将您的列表包含在 threading.Lock 中。
  • 您是否在请求处理程序的写入(到列表)之间切换上下文(例如使用await)?如果是,那么您必须将您的列表包含在 asyncio.Lock 中。
  • 您是否进行多处理?如果是,那么您必须使用multiprocessing.Lock
  • 您的应用程序是否划分到多台机器上?然后你必须使用一些外部共享数据库(例如 Redis)。

如果所有这些问题的答案都是,那么您无需执行任何操作,因为单线程异步应用无法并行更新共享资源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-10
    • 2021-09-24
    • 2011-05-11
    • 2019-10-07
    • 1970-01-01
    • 1970-01-01
    • 2019-03-07
    相关资源
    最近更新 更多