我将使用Stackless Python做什么?

zah*_*pov 42 python python-stackless

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

是的它有绿色线程(无堆栈),只要没有操作阻塞(像Ruby的线程?),它可以快速创建许多轻量级线程.这个有什么用?它有什么其他功能我想用于CPython?

Meh*_*Meh 30

它允许您使用大量的并发.没人理智会创建十万个系统线程,但你可以使用stackless来做到这一点.

本文测试了这一点,在Python和Google Go(一种新的编程语言)中创建了十万个tasklet:http://dalkescientific.com/writings/diary/archive/2009/11/15/100000_tasklets.html

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

Stackless适用于实现map/reduce算法,根据您的输入数据,您可以拥有大量的reducer.

  • @Adal:但是,mapless并不适合并行化,而Stackless在单CPU上运行所有tasklet吗? (3认同)

Kyl*_*tan 12

Stackless Python的主要好处是支持非常轻量级的协同程序.CPython本身并不支持协同程序(虽然我希望有人在评论中发布基于生成器的hack)所以当你遇到一个从协同程序中受益的问题时,Stackless是对CPython的明显改进.

我认为他们擅长的主要领域是当你在程序中运行许多并发任务时.示例可能是为其AI运行循环脚本的游戏实体,或者是为具有创建速度慢的页面的许多客户端提供服务的Web服务器.

然而,对于共享数据,您仍然存在许多典型的并发正确性问题,但确定性任务切换使得编写安全代码变得更加容易,因为您确切地知道控制将被转移到何处,因此知道共享状态必须的确切点.最新.

  • 这些任务是并发的,因为几个任务仍在进行中.执行只发生在其中一个中的事实是无关紧要的.由于等待I/O,大部分时间也适用于实际线程和进程.并说使用生成器的协同程序不是黑客就像在C++中使用setjmp/longjmp说coroutines不是一个黑客.:P系统可能已经设计为允许它,但它是一个很好的解决方案. (2认同)
  • 他们真的很绿,但不是真正的线程.与Python 3.3的"yield from"结构有一些相似之处,Guido正在研究一种名为"Tulip"的新的跨平台异步包.实际上,Stackless有超过10年的能力,可以做超轻量的绿色线程,但影响不大. (2认同)

zer*_*ble 8

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

(..)stackless通过允许将任务分成较小的任务Tasklet来进一步加剧这一点,然后可以将它们从主程序中分离出来以便自己执行.这可以用于即发即弃任务,例如发送电子邮件,调度事件,或用于IO操作,例如发送和接收网络数据包.一个tasklet等待来自网络的数据包,而其他任务继续运行游戏循环.

它在某些方面类似于线程,但是非抢占式和明确调度,因此同步问题较少.此外,在tasklet之间切换要比线程切换快得多,并且你可以拥有大量活动的tasklet,而线程的数量受到计算机硬件的严格限制.

(从这里得到这个引用)

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

此外,还有一个非常好的介绍材料,它描述了无堆栈为您的应用程序提供良好解决方案的原因.(可能有些陈旧,但我认为值得一读).


Thi*_*ler 6

EVEOnline主要在Stackless Python中编程.他们有几个关于使用它的开发博客.它似乎对高性能计算非常有用.

  • 为什么高性能计算会更好? (13认同)

rdw*_*rdw 6

虽然我没有使用Stackless本身,但我使用Greenlet来实现高度并发的网络应用程序.Linden实验室的一些使用案例包括:高性能智能代理,用于在大量机器上分配命令的快速系统,以及执行大量数据库写入和读取的应用程序(比率约为1) :2,这是非常重写的,所以它花费大部分时间等待数据库返回),以及内部Web数据的web-crawler-type-thing.基本上任何期望必须执行大量网络I/O的应用程序都将受益于能够创建bajillion轻量级线程.10,000个连接的客户对我来说似乎不是什么大不了的事.

尽管如此,Stackless或Greenlet并不是一个完整的解决方案.它们是非常低级的,你将不得不做很多的猴子工作来构建一个应用程序,使用它们最充分.我知道这是因为我维护了一个库,它在Greenlet之上提供了一个网络和调度层,特别是因为使用它编写应用程序非常容易.现在有很多这样的; 我维护了Eventlet,但也有Concurrence,Chiral,还有一些我不知道的东西.

如果您想要编写的应用程序类似于我所写的内容,请考虑其中一个库.Stackless vs Greenlet的选择比决定哪个库最适合您想要做的事情要重要得多.

  • 请注意,名称"Greenlet"具有误导性.就Stackless如何工作而言,Greenlets不是绿色,也许只是黄色;-)重点是Greenlets强制解释器通过修改C堆栈来切换上下文.Stackless可以本地协作方式实现这一点,这是内存和时间效率的5-10倍. (2认同)

por*_*uod 5

我认为绿色线程的基本用途是实现一个系统,在该系统中有大量对象执行高延迟操作.一个具体的例子是与其他机器通信:

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

线程允许您自然地编写上面的代码,但是如果对象的数量足够大,则线程无法充分执行.但是你可以使用绿色线程,即使是非常大的数量.在request_information()上面可以切换出一些调度,而其他的工作在等待,稍后再回来.您可以获得能够调用"阻塞"函数的所有好处,就好像它们在不使用线程的情况下立即返回一样.

如果您想以直接的方式编写代码,这显然对任何类型的分布式计算都非常有用.

多个核心缓解等待锁定也很有趣:

def Run():
    # Do some calculations
    green_lock(the_foo)
    # Do some more calculations
Run Code Online (Sandbox Code Playgroud)

green_lock函数基本上会尝试获取锁,如果由于其他核使用该对象而失败,则只切换到主调度程序.

同样,绿色线程被用于缓解阻塞,允许代码自然地编写并且仍然表现良好.

  • 其实你是完全错的.绿色线程是用户态线程.您在绿色线程中调用阻塞调用,整个解释器将被阻止.http://en.wikipedia.org/wiki/Green_threads"如果执行阻塞I/O操作,绿色线程可能会阻止所有其他线程." 这就是为什么在使用绿色线程时需要使用非阻塞IO的原因.绿色线程不会神奇地将阻塞呼叫变为非阻塞呼叫 (3认同)