作为gevent新手,请教greenlet是什么?它与线程有何区别?
Greenlet 到底是不是线程?答案是:绝对不是!
嘿,作为刚接触gevent的新手,纠结greenlet和线程的区别太正常啦!我来给你掰扯明白核心差异:
1. 调度逻辑完全不同
- 线程是抢占式调度:操作系统会主动给每个线程分配CPU时间片,哪怕当前线程还没执行完任务,系统也可能强行把CPU资源切换给其他线程,调度权完全在操作系统手里。
- Greenlet是协作式调度:只有当前greenlet主动让出CPU(比如调用
gevent.sleep()、触发IO操作、或者手动调用greenlet.switch()),其他greenlet才有机会运行。简单说就是“我不主动让,你就别想抢”。
2. 资源开销不在一个量级
- 线程:每个线程都需要操作系统分配独立的栈空间(通常是几MB级别),创建、销毁线程的开销都不小,操作系统层面的上下文切换成本也很高。
- Greenlet:作为用C实现的轻量级协程,每个greenlet的初始栈空间只有几KB,创建上千个greenlet都不会给系统带来太大压力,而且上下文切换完全在用户态完成,几乎没有额外开销。
3. 并发的本质不一样
- 线程属于操作系统级别的并发:多个线程可以在多核CPU上真正并行执行,充分利用硬件资源。
- Greenlet属于用户态的并发:所有greenlet都运行在同一个操作系统线程里,同一时间只有一个greenlet在执行,靠主动切换来模拟并发,本身没法利用多核。不过你可以结合gevent的
gevent.pool或者多进程来弥补这个短板。
举个直观的例子
假设你有两个计算型任务:
- 用线程的话,操作系统可能会让线程A跑10毫秒,然后强行切到线程B跑10毫秒,哪怕A还在埋头计算。
- 用greenlet的话,A会一直霸占CPU直到自己执行完毕,除非它中途主动触发了切换操作(比如加个
gevent.sleep(0)手动让出),否则B根本没机会运行。
你从《Learning Concurrency》里看到的描述完全准确——greenlet就是类线程的轻量级对象,能实现并发但又不用承担线程的开销,核心原因就是它是用户态自行管理的调度模型,和操作系统线程根本不是一个层面的东西~
内容的提问来源于stack exchange,提问作者MikiBelavista
相关产品推荐
相关产品推荐

