55

正如维基百科所说

绿色线程在不依赖任何本机操作系统功能的情况下模拟多线程环境,并且它们在用户空间而不是内核空间中进行管理,使它们能够在没有本机线程支持的环境中工作。

Python 的线程被实现为pthreads (kernel threads),并且由于全局解释器锁 (GIL),Python 进程一次只运行一个线程。

[问题]但是在Green-threads(或所谓的greenlet或tasklets)的情况下,

  1. GIL对他们有影响吗?一次可以运行多个greenlet吗?
  2. 使用greenlets或tasklet有什么陷阱?
  3. 如果我使用greenlets,一个进程可以处理多少个?(我想知道,因为在单个进程中,您最多可以打开 *ix 系统中设置的ulimit-s-v)线程。)

我需要一点洞察力,如果有人能分享他们的经验,或者引导我走上正确的道路,那将会有所帮助。

4

2 回答 2

33

您可以将 greenlets 视为更像是协作线程。这意味着没有调度程序在任何给定时刻在您的线程之间先发制人地切换 - 相反,您的 greenlet 在代码中的指定点自愿/明确放弃控制权。

GIL 会影响他们吗?一次可以运行多个greenlet吗?

一次只运行一个代码路径 - 优点是您可以最终控制哪个代码路径。

使用greenlets或tasklet有什么陷阱?

你需要更加小心——一个写得不好的greenlet不会让其他greenlet控制。另一方面,由于您知道 greenlet 何时会进行上下文切换,因此您可以避免共享数据结构创建锁。

如果我使用greenlets,一个进程可以处理多少个?(我想知道,因为在单个进程中,您可以将线程打开到 *ix 系统中设置的 umask 限制。)

使用常规线程,您拥有的调度程序开销越多。此外,常规线程仍然具有相对较高的上下文切换开销。Greenlets 没有与它们相关的这种开销。从瓶子文档中:

由于在切换和创建新线程时涉及的高开销,大多数服务器将其工作池的大小限制为相对较少的并发线程数。虽然线程与进程(分叉)相比便宜,但为每个新连接创建它们仍然很昂贵。

gevent 模块将 greenlets 添加到组合中。Greenlets 的行为类似于传统线程,但创建起来非常便宜。基于 gevent 的服务器可以生成数千个 greenlet(每个连接一个),几乎没有开销。阻止单个 greenlets 对服务器接受新请求的能力没有影响。并发连接的数量几乎是无限的。

如果您有兴趣,这里还有一些进一步的阅读:http: //sdiehl.github.io/gevent-tutorial/

于 2013-05-20T01:48:03.510 回答
6

我假设你在谈论 evenlet/gevent greenlets

1)只能运行一个greenlet

2)它是协作多线程,这意味着如果一个greenlet陷入无限循环,你的整个程序就会被卡住,通常greenlet要么显式调度,要么在I/O期间调度

3) 比线程多得多,这取决于可用的 RAM 量

于 2012-10-06T12:27:05.363 回答