nik*_*tiu 14 python asynchronous gevent flask
我最近一直在使用烧瓶在python中开展宠物项目.它是一个简单的pastebin,具有服务器端语法高亮支持pygments.因为这是一项代价高昂的任务,所以我将语法高亮显示委托给芹菜任务队列,并在请求处理程序中等待它完成.毋庸置疑,这只不过是减轻了对其他工作者的CPU使用率,因为等待结果仍会锁定与Web服务器的连接.尽管我的直觉告诉我要避免像瘟疫这样的过早优化,但我仍然无法帮助自己避免异步.
异步
如果最近一直关注python web开发,你肯定已经看到异步无处不在.异步的作用是带回合作多任务,这意味着每个"线程"决定何时何地屈服于另一个.这种非抢占式进程比OS线程更有效,但仍有其缺点.目前似乎有两种主要方法:
第一个通过在事件循环中执行的松散耦合组件提供并发性.尽管这在竞争条件方面更安全并且提供了更高的一致性,但与先发制人的多任务处理相比,它更不直观且更难编码.
另一个是更传统的解决方案,更接近线程编程风格,程序员只需手动切换上下文.虽然更容易出现竞争条件和死锁,但它提供了一个简单的插入式解决方案.
目前大多数异步工作都是在所谓的IO绑定任务上完成的,这些任务阻塞等待输入或输出.这通常通过使用可以调用的轮询和基于超时的函数来完成,如果它们返回负值,则可以切换上下文.
尽管名称,这也可以应用于CPU绑定任务,可以委托给另一个工作者(线程,进程等),然后非阻塞地等待产生.理想情况下,这些任务将以异步友好的方式编写,但实际上这意味着将代码分成足够小的块而不是阻塞,最好不要在每行代码之后分散上下文切换.这对于现有的同步库尤其不方便.
由于方便,我决定使用gevent进行异步工作,并想知道如何在异步环境中处理CPU绑定任务(使用期货,芹菜等?).
如何在传统的Web框架(例如flask)中使用异步执行模型(在本例中为gevent)?在python(期货,任务队列)中,这些问题有哪些常见的解决方案?
编辑:更具体 - 如何使用gevent与烧瓶以及如何在这种情况下处理CPU绑定的任务?
编辑2:考虑到Python如何使GIL阻止线程代码的最佳执行,这至少只留下了多处理选项.这意味着要么使用concurrent.futures,要么使用其他一些处理处理的外部服务(甚至可以为语言不可知的事情打开大门).在这种情况下,什么会是一些流行或经常使用gevent(即芹菜)的解决方案? - 最佳做法
执行类似以下操作以将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()
Run Code Online (Sandbox Code Playgroud)
如果您需要更复杂的东西,那么使用带有"Pool"的Flask-Celery或Multiprocessing库可能对您有用.
虽然我无法想象你可能需要什么样的复杂性或为什么,但我对gevent不太熟悉.
我的意思是如果你试图拥有一个主要的世界网站的效率,那么我建议构建C++应用程序来进行CPU密集型工作,然后使用Flask-celery或Pool来运行该过程.(这就是YouTube在混合使用C++和Python时的作用)
| 归档时间: |
|
| 查看次数: |
3375 次 |
| 最近记录: |