我可以用无栈Python做什么?
关于无栈Python(Stackless Python),有很多相关的问题。不过似乎没有人回答我这个问题,我觉得(如果我错了请纠正我!)。这个话题总是有人在讨论,所以我很好奇。无栈Python到底有什么用?它比CPython好在哪里?
没错,它有绿色线程(无栈线程),可以快速创建很多轻量级的线程,只要没有操作在阻塞(有点像Ruby的线程?)。这样有什么好处呢?它还有哪些其他功能是我想在CPython上使用的?
6 个回答
Thirler已经提到过,Eve Online使用了无栈(stackless)技术。需要注意的是:
(..) 无栈技术的一个特点是,它可以把任务分解成更小的任务,叫做任务单元(Tasklets),这些任务单元可以从主程序中分离出来,独立执行。这种方式适合一些不需要等待结果的任务,比如发送邮件、派发事件,或者进行输入输出操作,比如发送和接收网络数据包。一个任务单元可以在等待网络数据包的同时,其他任务单元继续运行游戏循环。
在某种程度上,这有点像线程,但它是非抢占式的,也就是说任务的切换是由程序自己控制的,因此在同步方面的问题会少一些。此外,任务单元之间的切换速度比线程切换快得多,而且你可以有很多活跃的任务单元,而线程的数量则受到计算机硬件的限制。
(这个引用来自这里)
在2009年的PyCon大会上,有人做了一场非常有趣的演讲,讲述了为什么以及如何在CCP Games中使用无栈技术。
另外,还有一份很好的入门材料,介绍了为什么无栈技术是你应用程序的一个好解决方案。(虽然可能有点旧,但我觉得值得一读。)
Stackless Python的主要好处是它支持非常轻量级的协程。CPython(标准的Python版本)并不原生支持协程(不过我想可能会有人在评论里分享基于生成器的解决方法),所以在需要使用协程的情况下,Stackless比CPython要好很多。
我认为它们特别适合处理程序中有很多同时进行的任务的情况。比如说,游戏中的角色需要运行一个循环脚本来控制它们的人工智能,或者一个网页服务器需要同时为很多客户提供页面,而这些页面生成得比较慢。
不过,你仍然会遇到一些与并发相关的常见问题,特别是关于共享数据的部分。但是,由于任务切换是确定性的,这让编写安全的代码变得更容易,因为你可以清楚地知道控制权会转移到哪里,从而知道共享状态必须在什么时刻保持最新。
这让你可以处理大量的并发操作。没有人会理智地创建十万个系统线程,但你可以通过使用stackless来做到这一点。
这篇文章测试了这个方法,分别在Python和Google Go(一个新的编程语言)中创建十万个任务:http://dalkescientific.com/writings/diary/archive/2009/11/15/100000_tasklets.html
令人惊讶的是,即使Google Go编译成了本地代码,并且他们宣传自己的协程实现,Python仍然胜出。
使用stackless非常适合实现map/reduce算法,这样你可以根据输入数据有很多个处理器。