无栈Python如何实现快速并发?
无栈Python(stackless python)在多核处理器上并没有很好地利用,所以它在哪些情况下应该比Python的线程或多进程更快呢?
所有的基准测试都是用无栈Python的任务来和Python的线程锁和队列进行比较,这样比较是不公平的,因为锁的效率总是比较低。
你看,如果使用单线程的函数调用不使用锁的话,它的效率应该和无栈Python差不多。
2 个回答
现在有一种新潮的东西叫做异步IO循环和消息传递并发,还有一些其他流行的术语。其实这些并不新鲜,只是在过去五年里才被大众所关注。
Stackless Python是Python的一种版本,它的虚拟机经过修改,更好地支持这些消息传递和IO循环。它的关键在于绿色线程和协程。
还有其他库也能实现类似的功能,比如Twisted和Tornado,这些都是Python中的工具。你甚至可以在Stackless Python上运行混合的Twisted等。
IO循环直接对应于伯克利套接字的异步IO,通过一些努力,它可以扩展为主动而非被动,并且可以与文件系统和网络套接字一起工作,比如最新的libevent。
要想利用多个核心进行横向扩展,有两种方法:多线程,即共享状态,比如线程或进程之间的共享;还有多进程,比如消息队列。当前架构的一般限制是,多线程在本地多个核心上表现良好,而当核心数量庞大或这些核心在不同机器上时,消息传递的性能会更好。你也可以采用混合的方法。
由于Python虚拟机内部设计的选择,通常在多线程方面的效率不如多进程,因此你会比在其他平台上更早地选择使用消息传递的多个进程。
不过,通常来说,消息传递的方法更干净,更容易纠正。
还有其他语言也基于这种方法,但有不同的目标和限制,比如Erlang、node.js、Clojure和Go。
在这些语言中,Clojure可能是最具启发性的。当你理解Clojure的运作方式,并思考其中的原因时,其他系统的整体目标和限制也会变得清晰...
先关注功能,再考虑性能(除非你确实需要)。
大部分时间,服务器在处理输入输出(I/O),所以多核处理器的优势不太明显。如果你主要在处理输入输出,使用多线程的Python可能是最简单的解决方案。
如果服务器的请求主要消耗CPU资源,那么有一个主进程(不管它是否是多线程的)和相应的子进程是很有意义的。
如果你真的想要扩展,可以考虑使用其他平台,比如Erlang。如果你想在扩展的同时继续使用Python,可以考虑在分布式集群上将Python进程作为Erlang端口来管理的分布式Erlang。
有很多选择,但除非你处理的是非常大的项目,否则你很可能可以采取简单的方法。
早发布,常发布。