在什么情况下,一个线程或执行者(使用线程)在asyncio
之上?
随着我使用Python(CPython)的经验的进步,它集中于优化工作中的脚本以批量执行某种形式的Web服务调用并处理响应。但是,经过几代脚本构建之后,我发现自己想知道为什么我不使用最新的脚本?
允许我在下面提供一些背景信息...
问题::从服务器A向客户端B请求N个文件,进行处理并将其保存到磁盘。
顺序
多线程
ThreadPoolExecutor
as_completed()
中会使用Queue and Thread结构asyncio
run_in_executor()
保存到磁盘因此,我们陷入了当前的困境:为什么我不要使用asyncio
进行I / O绑定工作?
异步编程是一个非常类似于OOP的概念,解决方案3的文档甚至说“异步执行可以通过线程执行”。但是,如果我可以在单个线程上实现异步执行(不包括用于阻止对磁盘进行I / O的附加线程),为什么还要使用解决方案1-3?
我知道在GIL的情况下,CPython多线程是次优的;无论如何,我认为没有理由再有人使用线程或执行程序了。我做了很多谷歌搜索,看是否能找到一篇很好的文章,说明为什么人们更喜欢使用它们,但是我只发现了一些文章,说明为什么线程(以及随后使用线程的执行程序)很糟糕:上下文切换( GIL / OS),竞争条件,资源匮乏等...
由于CPython不使用线程来利用多个核心CPU(我相信是multiprocessing
库),因此线程不用于繁重的计算任务;因此,将它们限制在I / O限制的操作中以提高性能。但是,那并没有给我足够的理由来理解为什么在asyncio
上使用线程或执行程序。
如果您可以在单个线程中(可能是2-3个)完成所有操作,为什么还要继续引入创建,管理和销毁线程的开销(无论是显式的还是通过池/执行器的)?
答案 0 :(得分:0)
我认为多线程和异步之间的决定实际上取决于您需要哪种多任务。如果一切都在程序的控制之下,那么异步/多处理可能一直都是正确的选择。但是,也许您想开始一项任务,在此前提下,多任务处理是正确的选择。例如,您在第三方库中启动任务。使用线程的一个显而易见的原因是该库不支持asyncio。但是,即使它支持异步,您也许也不想信任该库来随心所欲地控制您的任务。然后,您可以使用另一个运行该代码的asyncio事件循环来启动新线程。
所以我认为真正的问题是:什么时候使用合作社,什么时候使用抢占式多任务。