python-3.x - 使用 asyncio 而不是线程处理多个元素
问题描述
我有一个程序使用这样的 python 线程:启动 5 个线程并开始处理元素列表。
def process_element(element):
print(element)
jobs = Queue()
def do_stuff(q):
while not q.empty():
value = q.get()
process_element(element=value)
q.task_done()
for i in line: # my list of element
jobs.put(i)
for i in range(5):
worker = threading.Thread(target=do_stuff, args=(jobs))
worker.start()
jobs.join()
我怎样才能asyncio
用来做同样的工作。
解决方案
将您的代码直译为 asyncio 如下所示:
import asyncio, random
async def process_element(element):
print('starting', element)
await asyncio.sleep(random.random()) # simulate IO-bound processing
print('done', element)
async def do_stuff(q):
while not q.empty():
value = await q.get()
await process_element(element=value)
q.task_done()
async def main():
jobs = asyncio.Queue()
for i in range(20):
await jobs.put(i)
for i in range(5):
asyncio.create_task(do_stuff(jobs))
await jobs.join()
asyncio.run(main())
但请注意:
Asyncio 处理 IO 密集型任务,例如与 HTTP 服务器或远程数据库、聊天服务器等通信。它不处理 CPU 密集型任务,长时间运行的操作将阻塞整个事件循环。(在这种情况下,多线程或多处理更合适。)因此,将多线程代码“转换”为 asyncio 通常会失败。
while not q.empty(): ... process ...
在线程和异步中都是一种反模式,因为它不允许等待某些东西到达队列。如果您事先知道所有项目,则首先不需要队列,您可以使用普通列表。
推荐阅读
- r - 与多列匹配的字符串以在 r 中查找可能的结果
- prolog - 在 Mac 中输出序言
- php - CORS 在我的电脑上工作没有错误,但不能在任何其他设备上工作
- r - 迭代地将包含字符和数字的行添加到数据框中
- javascript - 为现有 JSDOC 注释的 commonJS 库创建 Typescript 声明文件
- angular - 在前一个关闭后一个一个打开几个 mat-dialogs
- azure - Azure 启动 2 个自托管服务器将文件交付到池中的 Azure 托管代理,但只有 1 个接受 copyfiles 任务
- javascript - 用纯 JS 在另一个 JS 文件中包含一个 JS 文件
- laravel - 分组或操作 laravel 集合
- linux - nginx + ssh_exchange_identification:连接被远程主机关闭