gevent 代码是运行在一个线程里面吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
hihihihihi

gevent 代码是运行在一个线程里面吗?

  •  
  •   hihihihihi 2016 年 8 月 31 日 3688 次点击
    这是一个创建于 3524 天前的主题,其中的信息可能已经有所发展或是发生改变。
    python 初学者, 偶然看到网上讨论 gevent ,于是把我之前的 thread 修改成了 gevent 的,

    但是我在调试的时候,发现 call stack 里面在调用那部分 gevent 代码的时候,新建了 10 来个新的线程

    不是说 gevent 都运行在一个线程里面吗?

    大致的伪代码如下:

    以前用多线程来做,
    1000 tasks, 分成 10 个线程,每个线程分 100 个 task ,等待所有线程退出


    现在的逻辑,一个 for 循环把所有的 tasks 分给 1000 个 gevent.spawn 调用, joinall 等待退出。


    问题 1 :是不是这里 for 循环 扔 1000 个 gevent.spawn 操作太暴力了?

    问题 2 :为什么后面换成 gevent 后,居然给我创建了 10 来个线程?
    11 条回复    2016-09-01 15:07:32 +08:00
    feisuzhu
        1
    feisuzhu  
       2016 年 8 月 31 日   1
    1. 不暴力,这样挺好(对你的程序来讲),不会有什么压力。被请求的资源可能就蛋疼了。可以的话还是用 gevent.pool.Pool 吧,就是把 gevent.spawn 改成 pool.spawn ,剩下的活 gevent 都帮你干了。

    2. 没明白。如果只是 gevent.spawn 的话,是不会有新线程的(除非底层的代码用了,而且你也没 monkey patch )。
    你说的是每个 task 都有自己的调用栈吧?这个是正常的。
    neoblackcap
        2
    neoblackcap  
       2016 年 9 月 1 日
    gevent 是里面是用的是协程,即用户态线程,若是指内核态线程的话那么就是一个,但用户态线程就不止一个,可能有成千上万个
    SlipStupig
        3
    SlipStupig  
       2016 年 9 月 1 日   1
    gevent 分两部分: 1.greenlet 2.libev
    1.greenlet ,原理是基于 stack 的,调度的方式是基于 coroutine 主动切换,说白了就是函数之间切换
    2.libev 这个主要涉及 IO 相关的,里面用的是线程池管理,这里面不是 coroutine ,所以只要你不做 IO 相关的操作不会是多线程的
    hihihihihi
        4
    hihihihihi  
    OP
       2016 年 9 月 1 日
    @feisuzhu

    协程函数代码里面是做了 IO 处理, urlopen 访问了网络, 刚才又测试了好多次, 这样一次性丢很多进去,程序内部可能会建立很多连接, timeout 出错概率变大,服务端也可能 drop 一些我的连接。

    而以前自己用线程来调度处理,服务器那边应该会觉得我友好一点?

    也许是我 gevent 还使用得不大对。
    hihihihihi
        5
    hihihihihi  
    OP
       2016 年 9 月 1 日
    @SlipStupig

    是的,我做了 IO 操作, 调用 urlopen 访问了网络。而且,一次性这样弄 1000 个 urlopen ,实测 timeout 概率增多,出错几率增大,是不是我这样用 gevent 是不对的。因为网络带宽和连接数始终是有限的。 比如如果我写的服务器,可能发现一次这么多并发连接,我可能会 drop 或者 block 掉一些。
    Zzzzzzzzz
        6
    Zzzzzzzzz  
       2016 年 9 月 1 日
    确实有线程, gevent 1.0 之后没设置环境变量 GEVENT_RESOLVER 为 ares 的话, 默认 DNS 查询一类操作走的是 gevent 自己封装的原生线程池的实现.
    SlipStupig
        7
    SlipStupig  
       2016 年 9 月 1 日
    @4ever911 这个不是别的,对方网站不一定扛得住,或者限制了.....
    petelin
        8
    petelin  
       2016 年 9 月 1 日
    超时的问题跟 gevent 没关系,你出口流量和对方入口流量限制,可能你以前的 10 个线程访问速度没有 gevent 来的快(很有可能),
    第二个我没看懂,感觉你的结果不对吧,话说你是怎么看出来线程数量的???
    hihihihihi
        9
    hihihihihi  
    OP
       2016 年 9 月 1 日
    @petelin Cannot type Chinese here on this device.

    I use VS Code as my Python IDE. Through the Debug Window, I see couple threads are created right after the gevent calls.

    I have tested both codes ( threads/gevent ) for many times. It seams that gevent runs a little bit faster. But, I guess the problem is not all about CPU, maybe I need pay more attention on the network connections.
    petelin
        10
    petelin  
       2016 年 9 月 1 日 via Android
    @4ever911 好吧,确实很神奇,期待大神来瞅瞅
    zhuangzhuang1988
        11
    zhuangzhuang1988  
       2016 年 9 月 1 日
    上代码..
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2831 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 40ms UTC 09:07 PVG 17:07 LAX 02:07 JFK 05:07
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86