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

2016-08-31 22:59:33 +08:00
 4ever911
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 来个线程?
3059 次点击
所在节点    Python
11 条回复
feisuzhu
2016-08-31 23:23:58 +08:00
1. 不暴力,这样挺好(对你的程序来讲),不会有什么压力。被请求的资源可能就蛋疼了。可以的话还是用 gevent.pool.Pool 吧,就是把 gevent.spawn 改成 pool.spawn ,剩下的活 gevent 都帮你干了。

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

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

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

也许是我 gevent 还使用得不大对。
4ever911
2016-09-01 09:35:33 +08:00
@SlipStupig

是的,我做了 IO 操作, 调用 urlopen 访问了网络。而且,一次性这样弄 1000 个 urlopen ,实测 timeout 概率增多,出错几率增大,是不是我这样用 gevent 是不对的。因为网络带宽和连接数始终是有限的。 比如如果我写的服务器,可能发现一次这么多并发连接,我可能会 drop 或者 block 掉一些。
Zzzzzzzzz
2016-09-01 10:14:16 +08:00
确实有线程, gevent 1.0 之后没设置环境变量 GEVENT_RESOLVER 为 ares 的话, 默认 DNS 查询一类操作走的是 gevent 自己封装的原生线程池的实现.
SlipStupig
2016-09-01 10:15:30 +08:00
@4ever911 这个不是别的,对方网站不一定扛得住,或者限制了.....
petelin
2016-09-01 10:41:24 +08:00
超时的问题跟 gevent 没关系,你出口流量和对方入口流量限制,可能你以前的 10 个线程访问速度没有 gevent 来的快(很有可能),
第二个我没看懂,感觉你的结果不对吧,话说你是怎么看出来线程数量的???
4ever911
2016-09-01 11:25:07 +08:00
@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
2016-09-01 13:09:57 +08:00
@4ever911 好吧,确实很神奇,期待大神来瞅瞅
zhuangzhuang1988
2016-09-01 15:07:32 +08:00
上代码..

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/303042

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX