30

我的不完全理解是 Twisted、Stackless、Greenlet、Eventlet、Coroutines 都使用了异步网络 IO 和用户态线程,这些线程非常轻量级且切换速度很快。但我不确定它们之间有什么区别。

它们听起来也与 Erlang 进程非常相似。它们几乎是一回事吗?

任何可以帮助我更多地理解这个主题的人将不胜感激。

4

3 回答 3

38

首先,非阻塞 I/O 与绿色线程或协程没有任何共同之处,但它会影响它们的调度方式。

现在:

  • Twisted是一个经典的非阻塞 I/O 框架——应用程序代码是使用回调以异步方式编写的。
  • Geventeventletgreenlet库用于协程/greenthreads/greenlets。有一个专用的 greenlet 用于运行事件循环(如果是 gevent,它是 C 编码的libevent的事件循环)。当任意 greenlet 开始等待某个 I/O 操作处理时,它只是将执行交给事件循环,该循环启动另一个 greenlet 执行(准备执行一些 I/O)。这被称为协作多任务——每个greenlet自己决定何时将控制权交还给其他greenlet。
  • Stackless有 tasklet,它类似于 greenlets,但也可以使用抢占式模型进行调度——这意味着调度程序可以随时停止 tasklet 执行并开始执行另一个 tasklet(这就是 OS 线程和 Erlang 进程的工作方式)。此外,Stackless 不提供任何开箱即用的非阻塞 I/O 设施,因此如果您通过 stdlib 进行 I/O - 它会阻塞整个 OS 线程,因此在您等待 I/O 时没有其他 tasklet 可以执行/O。已经尝试为 Stackless 提供 gevent 库的端口,但我不知道进展如何。
于 2010-11-24T06:26:55.447 回答
11

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

大体上:

  • 绞:单螺纹。通过使用“回调”和“延迟”习语实现非阻塞行为。类似于 node.js。
  • greenlet / eventlet :使用“绿色线程”(内存部分?)来实现非阻塞 io。实际上用它们的版本修补了标准 CPython IO,所以代码仍然像阻塞/顺序一样编写。
  • 无堆栈:http : //www.stackless.com/。没用过,好像增加了“微线程”和其他细节? 无堆栈示例习语
  • 协程: SO 上的协程

这些都不像 Erlang 进程那样轻巧或得到很好的支持。

于 2010-11-24T04:13:23.923 回答
11

将 Stackless 与 Greenlet 进行比较时,您几乎是对的。缺少的是:

Stackless 本身并没有添加任何东西。相反,在 Stackless 5 年后发明的 Greenlet 删除了某些东西。它编写得足够简单,可以构建为扩展模块而不是替代解释器。

这真的很有趣——Stackless 有更多的功能,切换效率提高了大约 10 倍,并提供了执行状态的酸洗。

Greenlet 仍然获胜,这可能只是因为作为扩展模块易于使用。所以我正在考虑通过用酸洗扩展 Greenlet 来恢复这个过程。也许这会再次改变情况:-)

于 2012-03-18T20:43:55.767 回答