Python3异步编程中如何在并发任务之间共享资源

8

我有一个用Python3.5编写的网络应用程序,利用了Python的Asyncio并发处理每个传入的连接。

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


如果你正在进行HTTP开发,建议使用aiohttp,它可以为你处理所有相关事项(据我所知)。 - Wayne Werner
2个回答

8

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

但是,如果仍然存在竞争条件(这取决于具体的代码结构),您可以使用asyncio同步原语队列


每个客户端连接都由一个单独的任务处理。在每个任务中,当处理客户端时,数据将附加到全局列表中。task = asyncio.Task(self._handle_client(client_reader, client_writer)) self.clients[task] = (client_reader, client_writer)并且在_handle_client中,该列表被附加到。如果两个客户端恰好同时连接,这会导致问题吗? - Cellydy
不,这很安全。 - Andrew Svetlov

4

你的问题中缺少许多信息。

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

如果所有这些问题的答案都是“否”,那么你不需要做任何事情,因为单线程异步应用程序无法并行更新共享资源。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接