gpt4 book ai didi

Python 异步和 CPU 密集型任务?

转载 作者:太空狗 更新时间:2023-10-29 17:19:47 26 4
gpt4 key购买 nike

我最近一直在使用 flask 在 python 中开发一个宠物项目。它是一个简单的 pastebin,具有服务器端语法高亮支持 pygments。因为这是一项代价高昂的任务,所以我将语法突出显示委托(delegate)给 celery 任务队列,并在请求处理程序中等待它完成。不用说,这只不过是减轻了另一个 worker 的 CPU 使用率,因为等待结果仍然会锁定与 web 服务器的连接。尽管我的直觉告诉我要避免像瘟疫这样的过早优化,但我仍然无法帮助自己研究异步。

异步

如果最近一直在关注 python web 开发,您肯定已经看到异步无处不在。 async 所做的是恢复协作式多任务处理,这意味着每个“线程”决定何时何地让步给另一个线程。这种非抢占式进程比 OS 线程更高效,但仍有其缺点。目前似乎有两种主要方法:

  • 事件/回调风格的多任务处理
  • 协程

第一个通过在事件循环中执行的松耦合组件提供并发性。虽然这在竞争条件方面更安全并且提供了更多的一致性,但它比抢占式多任务处理更不直观且更难编码。

另一种是更传统的解决方案,更接近线程编程风格,程序员只需手动切换上下文。虽然更容易出现竞争条件和死锁,但它提供了一个简单的直接解决方案。

目前大多数异步工作都是在所谓的 IO-bound 任务上完成的,这些任务会阻塞以等待输入或输出。这通常是通过使用可以调用的基于轮询和超时的函数来实现的,如果它们返回否定,则可以切换上下文。

尽管名称如此,这也可以应用于 CPU 绑定(bind) 任务,这些任务可以委托(delegate)给另一个工作人员(线程、进程等),然后非阻塞地等待让步。理想情况下,这些任务将以异步友好的方式编写,但实际上这意味着将代码分成足够小的 block 而不会阻塞,最好不要在每行代码后分散上下文切换。这对于现有的同步库来说尤其不方便。


由于方便,我决定使用 gevent 进行异步工作,并且想知道如何在异步环境中处理 CPU 绑定(bind)任务(使用 futures、celery 等?)。

如何将异步执行模型(本例中为 gevent)与 Flask 等传统 Web 框架一起使用? python 中的这些问题( future 、任务队列)有哪些普遍认可的解决方案?

编辑:更具体地说 - 如何将 gevent 与 flask 一起使用以及如何在这种情况下处理 CPU 密集型任务?

EDIT2: 考虑到 Python 如何具有阻止线程代码最佳执行的 GIL,这只剩下多处理选项,至少在我的情况下是这样。这意味着要么使用 concurrent.futures 要么使用其他处理处理的外部服务(甚至可以为语言不可知的东西打开大门)。在这种情况下,使用 gevent(i.e. celery) 的一些流行或常用的解决方案是什么? - 最佳实践

最佳答案

像下面这样将 cpu 密集型任务分离到异步线程中应该是线程安全的:

from threading import Thread

def send_async_email(msg):
mail.send(msg)

def send_email(subject, sender, recipients, text_body, html_body):
msg = Message(subject, sender = sender, recipients = recipients)
msg.body = text_body
msg.html = html_body
thr = Thread(target = send_async_email, args = [msg])
thr.start()

如果您需要更复杂的东西,那么 Flask-Celery 或带有“Pool”的多处理库可能对您有用。

我对 gevent 不太熟悉,但我无法想象您可能需要更多的复杂性或原因。

我的意思是,如果您想要提高大型世界网站的效率,那么我建议构建 C++ 应用程序来完成您的 CPU 密集型工作,然后使用 Flask-celery 或 Pool 来运行该进程。 (这就是 YouTube 在混合使用 C++ 和 Python 时所做的)

关于Python 异步和 CPU 密集型任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15969213/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com