Python/Erlang:Twisted、Stackless、Greenlet、Eventlet、协程有什么区别?它们与Erlang进程相似吗?

31 投票
3 回答
7782 浏览
提问于 2025-04-16 07:31

我对这个话题的理解还不太完整,Twisted、Stackless、Greenlet、Eventlet和协程这些东西都是利用异步网络输入输出和非常轻量级的用户线程,这些线程切换起来很快。但是我不太确定它们之间有什么区别。

另外,它们听起来和Erlang的进程很相似。它们是不是差不多一样的东西呢?

如果有人能帮我更好地理解这个话题,我将非常感激。

3 个回答

11

上钩了!(欢迎修正!):

简单来说:

  • 扭曲的:单线程。通过使用“回调”和“延迟”这种方法来实现非阻塞的行为。和node.js有点像。
  • greenlet / eventlet:使用“绿色线程”(内存的某些部分?)来实现非阻塞的输入输出。实际上是用他们的版本替换了标准的CPython输入输出,所以代码写起来还是像是阻塞的/顺序的。
  • 无栈:http://www.stackless.com/。我没用过,看起来是增加了“微线程”和其他一些好东西?无栈示例习惯用法
  • 协程:StackOverflow上的协程

这些都没有Erlang进程那么轻量或支持得那么好。

12

你在比较 Stackless 和 Greenlet 的时候,基本上是对的。不过,有一点需要补充:

Stackless 本身并不是在增加什么东西。相反,Greenlet 是在 Stackless 之后五年发明的,它去掉了一些东西。Greenlet 的设计很简单,可以作为一个扩展模块来使用,而不是替代整个解释器。

这真的很有趣——Stackless 有更多的功能,在切换时效率大约高出 10 倍,还能保存执行状态。

不过,Greenlet 还是赢了,可能只是因为它作为扩展模块使用起来更简单。所以我在考虑通过扩展 Greenlet 来加入保存功能。也许这样会改变现状,谁知道呢 :-)

38

首先,非阻塞I/O和绿色线程或协程没有直接关系,但它会影响它们的调度方式。

现在来看看:

  • Twisted 是一个经典的非阻塞I/O框架——应用代码是用异步风格编写的,使用回调函数。
  • Geventeventlet 使用 greenlet 库来处理协程/绿色线程/绿色小任务。每个绿色小任务都有一个专门的绿色小任务来运行事件循环(在gevent中,这个事件循环是用C语言编写的 libevent)。当某个绿色小任务开始等待某个I/O操作时,它会把执行权交给事件循环,事件循环会启动另一个准备好进行I/O的绿色小任务。这种方式叫做协作式多任务处理——每个绿色小任务自己决定什么时候把控制权交给其他绿色小任务。
  • Stackless 有任务小任务(tasklets),它们类似于绿色小任务,但可以用抢占式模型调度——这意味着调度器可以随时停止一个任务小任务的执行,开始执行另一个任务小任务(这和操作系统线程和Erlang进程的工作方式相似)。另外,Stackless本身不提供任何非阻塞I/O的功能,所以如果你通过标准库进行I/O操作,它会阻塞整个操作系统线程,这样在等待I/O时就没有其他任务小任务可以执行。虽然有人尝试为Stackless提供gevent库的移植,但我不太清楚进展如何。

撰写回答