我会用Stackless Python做什么?

有很多与Stackless Python有关的问题。 但是没有人回答我的问题,我想(请纠正我,如果错了,请!)。 有一些关于它的嗡嗡声,所以我好奇知道。 我会用什么Stackless? 它怎么比CPython好?

是的,它有绿色线程(无堆栈),只要没有任何操作被阻塞,就可以快速创build许多轻量级的线程(比如Ruby的线程?)。 这是什么伟大的? 还有什么其他的function,我想通过CPython使用?

它允许您处理大量的并发。 没有人会创build十万个系统线程,但是你可以使用无堆栈来完成。

本文将testing如何在Python和Google Go(一种新的编程语言)中创build10万个tasklet: http : //dalkescientific.com/writings/diary/archive/2009/11/15/100000_tasklets.html

令人惊讶的是,即使Google Go被编译为本地代码,并且他们吹嘘他们的协同例程实现,Python仍然赢。

Stackless对于实现map / reducealgorithm非常有用,在这种algorithm中,根据input数据,可以有大量的reducer。

Stackless Python的主要优点是支持非常轻量级的协程。 CPython本身不支持协程(虽然我希望有人在注释中发布一个基于生成器的hack),所以当你有一个从协程中受益的问题时,Stackless是对CPython的一个明显的改进。

我认为他们擅长的主要领域是在程序中运行许多并发任务。 例子可能是为AI运行循环脚本的游戏实体,或者是服务于许多客户端的网页创build缓慢的网页服务器。

然而,关于共享数据,您仍然有很多并发正确性的问题,但确定性的任务切换使编写安全代码变得更容易,因为您确切知道控制权在哪里传输,因此知道共享状态的确切点最新。

Thirler已经提到Eve Online中使用了stackless。 请记住:

(..)stackless通过允许任务被分离成更小的任务,Tasklets,然后可以从主程序分离出来执行自己,进一步扭曲。 这可以用于“即发即忘”任务,如发送电子邮件或调度事件,或者用于IO操作,例如发送和接收networking数据包。 一个tasklet等待来自networking的数据包,而另一个则继续运行游戏循环。

它在某些方面与线程相似,但是非抢先式和明确调度,所以同步问题更less。 另外,在tasklet之间切换比线程切换快得多,并且可以拥有大量活动的tasklet,而线程的数量受到计算机硬件的严格限制。

(从这里得到这个引用)

在PyCon 2009上,有一个非常有趣的演讲 ,描述了为什么以及如何在CCP Games上使用Stackless。

此外,还有一个非常好的介绍材料 ,它描述了为什么stackless是您的应用程序的一个很好的解决scheme。 (可能有点旧了,但是我认为值得一读)。

EVEOnline在很大程度上是用Stackless Python编程的。 他们有几个关于使用它的开发博客。 看来这对高性能计算非常有用。

虽然我没有使用Stackless,但我已经使用Greenlet来实现高度并发的networking应用程序。 林登实验室的一些用例是:高性能智能代理,一个用于在大量机器上分发命令的快速系统,以及一个执行大量数据库写入和读取的应用程序(比例约为1 :2,这是非常重要的,所以它的大部分时间花在等待数据库返回),以及一个web内容networking爬虫types的东西。 基本上任何期望必须执行大量networkingI / O的应用程序都可以从创build一个bajillion轻量级线程中受益。 10,000个连接的客户对我来说似乎不是什么大事。

尽pipe如此,Stackless或Greenlet并不是一个完整的解决scheme。 他们是非常低级的,你将不得不做大量的猴子工作,与他们build立一个应用程序,充分利用他们。 我知道这一点,因为我维护一个在Greenlet之上提供networking和调度层的库,特别是因为编写应用程序非常容易。 现在有一大堆 我维护Eventlet,但也有Concurrence,Chiral,可能还有一些我不知道的。

如果你想写的应用程序听起来像我写的东西,考虑这些库之一。 Stackless vs Greenlet的select比决定什么样的图书馆最适合你想要做的事情要重要得多。

绿色线程的基本用处,就像我看到的那样,是实现一个系统,在这个系统中有大量的对象执行高延迟操作。 一个具体的例子是与其他机器通信:

def Run(): # Do stuff request_information() # This call might block # Proceed doing more stuff 

线程可以让你自然地编写上面的代码,但是如果对象的数量足够大,线程就不能充分执行。 但是你甚至可以使用绿色的线程。 上面的request_information()可以切换到其他工作正在等待的地方,稍后返回。 你可以调用“阻塞”函数的所有好处, 就好像它们立即返回而不使用线程一样。

如果你想以直接的方式编写代码,这对于任何types的分布式计算都是非常有用的。

多核心缓解等待locking也是有趣的:

 def Run(): # Do some calculations green_lock(the_foo) # Do some more calculations 

green_lock函数基本上会尝试获取锁,如果由于使用该对象的其他内核而导致失败,则仅切换到主调度器。

再次,绿色线程正在用来减轻阻塞,允许代码自然写入,仍然performance良好。