下面我附上了一个测试程序来演示asyncio.gather抛出类型错误的问题。
我的目标是:进行多个并发异步调用,从连接到我的计算机上的一组USB摄像头将摄像头图像捕获到文件中。当所有相机都完成了异步捕获后,我希望恢复处理。
这里显示的异步协程take_image()对ffmpeg应用程序进行系统调用,该应用程序从指定的摄像机捕获图像到指定的文件。
import asyncio
import os
import subprocess
import time
async def take_image(camera_id, camera_name, image_file_path, image_counter):
image_capture_tic = time.perf_counter()
try:
run_cmd = subprocess.run( ["ffmpeg", '-y', '-hide_banner', '-f', 'avfoundation', '-i', camera_id,
'-frames:v', '1', '-f', 'image2', image_file_path], universal_newlines=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Note, ffmpeg writes to stderr, not stdout!
except Exception as e:
print("Error: Unable to capture image for", image_file_path)
return "NO IMAGE!"
image_capture_toc = time.perf_counter()
print(f"{image_counter}: Captured {camera_name} image in: {image_capture_toc - image_capture_tic:0.0f} seconds")
return camera_name
下面显示的main()例程获取多个摄影机的列表,并对列表中的每个摄影机进行迭代,main()使用asyncio.create_task()为每个摄影机创建一个asyncio任务。每个任务都会添加到任务列表中。
一旦所有的图像捕获任务已经开始,我等待他们完成使用等待asyncio.gather(任务)。
async def main():
tic = time.perf_counter()
camera_list = [('0', 'FHD Camera #1'), ('1', 'FHD Camera #2'), ('2', 'FHD Camera #3'), ]
image_counter = 1
tasks = []
for camera_pair in camera_list:
camera_id, camera_name = camera_pair
image_file_name = 'img' + str(image_counter) + "-cam" + str(camera_id) + "-" + camera_name + '.jpg'
image_file_path = os.path.join("/tmp/test1/img", image_file_name)
# schedule all image captures calls *concurrently*:
tasks.append(asyncio.create_task(take_image(camera_id, camera_name, image_file_path, image_counter),
name=image_file_name))
image_counter = image_counter + 1
await asyncio.gather(tasks) # <-- This line throws a TypeError!
toc = time.perf_counter()
print(f"Captured list of {image_counter - 1} cameras in: {toc - tic:0.0f} seconds")
asyncio.run(main())
不幸的是,当我试图运行这个程序,我得到了这个错误:
TypeError:不可损坏的类型:“列表”
以及以下回溯:
Traceback (most recent call last):
File "scratch_10.py", line 41, in <module>
asyncio.run(main())
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/base_events.py", line 608, in run_until_complete
return future.result()
File "scratch_10.py", line 36, in main
await asyncio.gather(tasks)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/tasks.py", line 805, in gather
if arg not in arg_to_fut:
TypeError: unhashable type: 'list'
我一直在试图通读有关asyncio的3.8文档,但我不明白哪里出了问题。
如何让每个take_image请求异步运行,然后在每个任务完成后在调用例程中恢复处理?
你应该试试:(Task1,Task2,Task3)这就是我为任务所做的,而且它起作用了
gather
接受位置参数,而不是一个单一的可编辑参数。你需要打开你的清单。
await asyncio.gather(*tasks)
问题内容: 好吧,我安装了elasticsearch-rails gem(版本0.1.5),并且可以清楚地看到gem文件中的任务。 但是当我跑步时 我得到这个错误。 运行也不显示任务。 elasticsearch正在运行,如果我卷曲它会回应我。 为什么这不起作用? 问题答案: 您需要创建elasticsearch.rake
3.3.3 Android 任务 Android plugin 使用了同样的约定规则以和其他插件保持兼容,并且又添加了一些额外的引导任务: assemble 这个任务会汇集工程的所有输出。 check 这个任务会执行所有校验检查 connectedCheck 运行 checks 需要一个连接的设备或者模拟器,这些checks将会同时运行在所有连接的设备上。 deviceCheck 通过 API 连
我有一个表,其列如下所示: 符号 区域 国家 位置 日期 计数 我创建了如下表: null 简单地说,我想要支持where子句中所有或任意数量列的表结构。 在卡桑德拉有可能做到这一点吗?
执行 gradle tasks 命令会列出项目中所有任务. 这会显示项目中所有的默认任务以及每个任务的描述. 例 11.9 获取任务信息 gradle -q tasks 命令的输出 > gradle -q tasks ------------------------------------------------------------ All tasks runnable from root p
3.3.2 Java 工程任务 Java plugin 创建了两个主要的任务,主要的引导任务都依赖他们。 assemble jar 这个任务创建所有输出 check test 这个任务运行所有测试 jar 任务直接或者间接的依赖其他任务:比如 classes 会编译所有Java代码. testClasses 会编译所有测试,但是它很少使用,因为 test 这个任务依赖它(和 classes 差不多
Android plugin 使用相同的约定以兼容其他插件,并且附加了标志性的 task,包括: assemble 组合项目所有输出 check 执行所有检查 connectedCheck 在一个连接的设备或者模拟器上执行检查,它们可以在所有连接的设备上并行执行检查 deviceCheck 通过 APIs 连接远程设备来执行检查,主要用于 CI(Continuos integration ,持续集