Python Asynio:无法运行并行Asynio例程
我使用Asyncio并行处理58个摄像头。首先,我尝试从opencv python的imread方法加载所有图像。我尝试了这两种方法,正常的方法(顺序)和Asynio,但它们都花费了几乎相同的时间Python Asynio:无法运行并行Asynio例程,python,python-asyncio,Python,Python Asyncio,我使用Asyncio并行处理58个摄像头。首先,我尝试从opencv python的imread方法加载所有图像。我尝试了这两种方法,正常的方法(顺序)和Asynio,但它们都花费了几乎相同的时间 async def loadImage(i): return base64.b64encode(cv2.imread(my_local_path)).decode('utf-8') def loadImageSync(i): return base64.b64encode(cv2.
async def loadImage(i):
return base64.b64encode(cv2.imread(my_local_path)).decode('utf-8')
def loadImageSync(i):
return base64.b64encode(cv2.imread("frames_set/Kamera {}.jpg".format(i))).decode('utf-8')
主功能
async def main():
starttime_lmSync = time.time()
lm = [loadImageSync(i) for i in range(1,59)]
print("Loading Images {}".format(time.time() - starttime_lmSync))
starttime_lm = time.time()
lm = [loadImage(i) for i in range(1,59)]
rawImage = await asyncio.gather(*lm)
print("Loading Images aSync {}".format(time.time() - starttime_lm))
输出:
正在加载图像1.320235013961792
加载映像异步1.3253769874572754
我做错了什么?或者这是预期的结果
加载一批图像后,我想对它们进行解码并将其转换为numpy数组。对于单个图像,它需要约0.02秒,因此为了在Parralel中处理所有图像,我使用asynio
async def process_image(im):
return np.asarray(np.frombuffer(base64.b64decode(im), np.uint8),dtype=np.float32).reshape((1080,1920,3))
starttime_process = time.time()
futures = [process_image(img_b64) for img_b64 in rawImage]
res = await asyncio.gather(*futures)
print("total time taken {}".format(time.time() - starttime_process))
输出
总耗时1.2220990657806396
同样,它所花费的时间几乎等于顺序调用所花费的时间。有什么东西我遗漏了吗
Python版本:3.7
OS:Ubuntu16.04你的
loadImage
函数不是一个合作的协同程序,因此即使你使用了asyncio.gather
来并行生成它们,它们也会阻塞线程
您需要通过使用线程池将任务委派给不同的线程,以便每个协同程序在单独的线程中运行,而不会相互阻塞
下面是一种使用线程池执行器的方法:
executor = concurrent.futures.ThreadPoolExecutor(max_workers=60)
由于大多数线程都是I/O绑定的,所以生成60应该不是一个大问题
现在,您可以修改loadImage
如下:
async def loadImage(i, event_loop, executor):
return base64.b64encode(await event_loop.run_in_executor(executor, cv2.imread, my_local_path)).decode('utf-8')
上面的内容应该使loadImage
成为一个(合作的)协同程序,并且您应该看到I/O绑定任务的速度提高
(产生这么多线程和分配资源可能会对速度造成一定的损失)。嘿,我希望你能从其他人那里得到更全面的答案-->但我认为你只会看到在等待时间很长的代码中使用asyncio可以显著提高速度。据我所知,代码只是在处理数据,这就是为什么您没有看到显著的性能差异。谢谢@ilamaaa。有道理。那么,python中有没有一种方法可以在不使用asynio的情况下加快速度呢。我也试过穿线,但结果几乎是一样的。我一直想好好测试一下这些家伙,巩固我对这些优点和缺点的理解,但我从来没有真正去做过。希望看到您使用多个进程的结果。我尝试了POOL、Threadpool和进程,但时间没有变化:/谢谢。然而,在我的例子中,在使用asyncio之前,我一直在使用线程,但在阅读了您的评论之后,我意识到这个实现也将使用线程,所以我必须不断地聆听这60个流。所以我有一些问题,asyncio在我的案例中值得吗?从python线程转移到asyncio会给我带来一些好处吗?你能为我的用例推荐一个更好的方法吗@heemayl@shahidammer我的经验法则是:如果任务是I/O绑定的,那么选择async
;如果任务是CPU绑定的,那么选择multiprocessing
。在我的用例中,这60个工人将全天候(在无限循环中)获得实时流。考虑到这一点,在资源方面,使用asyncio比使用线程有什么好处吗?@shahidammerasyncio
尝试在单个线程中进行协作多任务处理。在这种情况下,您需要生成一个线程池,将任务推送到线程池中进行工作,因为您的函数不是天生的协作例程。但由于事件循环将完成编排,我认为您肯定会从纯线程中获益。@shahidammer很高兴我能提供帮助。我想强调的是,就性能而言,在做出决定之前,您应该始终进行基准测试。