python asyncio.gather vs asyncio.as_在IO任务后跟CPU绑定任务时完成

python asyncio.gather vs asyncio.as_在IO任务后跟CPU绑定任务时完成,python,python-asyncio,Python,Python Asyncio,我有一个程序工作流程如下:1。IO绑定(网页获取)->2。cpu限制(处理信息)->3。IO绑定(将结果写入数据库) 我目前正在使用aiohttp获取网页。我目前正在使用asyncio.as_completed收集步骤1的任务,并在完成时将它们传递给步骤2。我担心的是,这可能会通过消耗cpu资源和阻塞步骤2中的程序流来干扰步骤1任务的完成 我曾尝试使用ProcessPoolExecutor将步骤2任务分包给其他进程,但步骤2任务使用不可pickle的数据结构和函数。我曾经尝试过ThreadPoo

我有一个程序工作流程如下:1。IO绑定(网页获取)->2。cpu限制(处理信息)->3。IO绑定(将结果写入数据库)

我目前正在使用aiohttp获取网页。我目前正在使用asyncio.as_completed收集步骤1的任务,并在完成时将它们传递给步骤2。我担心的是,这可能会通过消耗cpu资源和阻塞步骤2中的程序流来干扰步骤1任务的完成

我曾尝试使用ProcessPoolExecutor将步骤2任务分包给其他进程,但步骤2任务使用不可pickle的数据结构和函数。我曾经尝试过ThreadPoolExecutor,虽然它有效(例如,它没有崩溃),但我的理解是,对CPU限制的任务这样做会适得其反

因为工作流有一个中间的cpu绑定任务,所以在继续执行步骤2之前,使用asyncio.gather(而不是asyncio.as_completed)来完成所有步骤1过程是否会更有效

示例asyncio.as_完成的代码:

将ClientSession()作为会话进行异步: tasks={self.url中url的self.fetch(会话,url)} 对于异步IO中的任务。完成时(任务): 原始数据=等待异步IO.shield(任务) 数据=自身。提取数据(*原始数据) 等待自存数据(数据) 示例asyncio.gather代码:

将ClientSession()作为会话进行异步: tasks={self.url中url的self.fetch(会话,url)} 结果=等待asyncio.gather(*任务) 对于结果中的结果: 数据=自身。提取数据(*结果) 等待自存数据(数据) 使用有限样本进行的初步测试表明,完成时的效率略高于采集时的效率:~2.98s(完成时)vs~3.15s(采集)。但是有没有一个异步IO概念问题会让一个解决方案优于另一个解决方案?

“我已经尝试了ThreadPoolExecutor,[…]我的理解是,对CPU限制的任务这样做会适得其反。”-从某种意义上说,这是countrproductiv,您不会有两个这样的任务并行运行Python代码,使用多个CPU核-但除此之外,如果一次只为一个任务咀嚼代码,那么可以释放异步IO循环以继续工作

如果无法将内容pickle到子流程,那么在ThreadPoolExecutor中运行CPU绑定的任务就足够了

否则,只需在cpu代码中撒上一些
等待asyncio.sleep(0)
(在循环中)并将它们作为协程正常运行:这足以让cpu绑定的任务不锁定asyncio循环