我最近一直在使用烧瓶在python中进行宠物项目。这是一个简单的pastebin,带有pygments的服务器端语法突出显示支持。因为这是一个代价高昂的任务,我将语法突出显示委托给一个芹菜任务队列,并在请求处理程序中等待它完成。不用说,这只不过是减轻了另一名工作人员的CPU使用量,因为等待结果仍然会锁定与Web服务器的连接。 尽管我的直觉告诉我要避免像瘟疫一样的过早优化,但我仍然无法帮助自己寻找异步。Python异步和CPU绑定任务?
异步
如果最近一直下面的Python Web开发,你一定已经看到,异步无处不在。 async做的是带回合作多任务,这意味着每个“线程”决定何时何地屈服于另一个线程。这种非抢先式进程比OS线程更有效,但仍然有缺点。目前,似乎有两个主要途径:
- 事件/回调风格的多任务
- 协同程序
第一个通过一个事件循环执行的松耦合组件提供并发。虽然这对于竞争条件来说更安全并且提供了更多的一致性,但它比直接的多任务更直观,更难以编码。
另一种是比较传统的解决方案,更接近线程化编程风格,程序员只需手动切换上下文。虽然更容易出现竞态条件和死锁,但它提供了一种简单的插入式解决方案。
目前大多数异步工作都是在所谓的IO-bound上完成的任务,阻塞等待输入或输出的任务。这通常是通过使用基于轮询和基于超时的功能来完成的,如果它们返回负值,则可以切换上下文。
尽管名字,这可应用于CPU绑定任务也可以委托给其他员工(线程,进程等),然后无阻挡地等待屈服。理想情况下,这些任务将以异步友好的方式编写,但实际上这意味着将代码分成足够小的块以防止块,最好在每行代码之后不散射上下文切换。这对现有的同步库尤其不便。
由于方便,我定居在使用异步工作GEVENT,并想知道如何与在异步环境CPU密集型任务进行处理(利用期货,芹菜等?)。
如何在传统Web框架(如瓶子)中使用异步执行模型(本例中为gevent)? python中的这些问题(期货,任务队列)中的一些普遍认可的解决方案是什么?
编辑:更具体的 - 如何使用gevent与烧瓶以及如何处理在这种情况下的CPU绑定任务?
EDIT2:考虑到Python的GIL是如何阻止线程代码的优化执行的,所以这只留下多处理选项,至少在我的情况下。这意味着要么使用并发期货要么处理一些其他外部服务(可以为某些语言不可知的情况打开大门)。在这种情况下,什么会是一些流行或经常使用的gevent解决方案(,即芹菜)? - 最佳实践
您几乎可以在每个库中采用此模式:http://bottlepy.org/docs/dev/async.html#event-callbacks。我建议'常青树',因为它允许通过集成'concurrent.futures'的修改版本来将合作任务(greenlet)与长时间运行的任务相结合。 – schlamar