关于 gevent 的一个另类用法

2012-10-01 04:45:31 +08:00
 phuslu
这个用法的故事如下:

一开始, 我们只是 gevent 的轻度用户, 我们在自己的代码里面写着 SocketServer, threading 的代码, 那时候我们只要写完了, 在文件头部使用这样的语法就差不多觉得足够了

import gevent.monkey
gevent.monkey.patch_all()

顶多检测一下gevent的版本(众所周知0.13.x版本的 dns 解析很不稳定), 那么我们的代码会变成这样了

import gevent, gevent.monkey
gevent.monkey.patch_all(dns=gevent.version_info[0]>=1)

到后来, 我们逐渐习惯了 gevent 的思维方式, 就开始大量在我们的新代码中使用诸如 gevent.spawn, gevent.pool, gevent.server.StreamServer 等等"纯粹"的 gevent 的类和函数.
我们甚至觉得 gevent.monkey.patch_all 是 ugly&dirty 的, 如果不是为了兼容第三方库, 我们才不会使用 gevent.monkey.patch_all 呢.

于是乎, python 网络编程在 gevent 的帮助下变得高效而优雅.
直到有一天, 我们需要把我们的程序拿到一个没有 gevent 环境下运行, 又或者, 我们需要在一个没有 gevent 的环境下写网络程序, 而此时我们都几乎忘了 threading, SocketServer 的用法了.

如何你也有相同的遭遇, 我觉得下面一段"另类"的代码或许能展示一个简单的思路.

http://gist.github.com/3808393
6585 次点击
所在节点    Python
3 条回复
Js
2012-10-01 11:54:17 +08:00
赞, 但是有个容易导致结果不一致的情况,毕竟在gevent多个协程里操作不涉及IO的变量是不用加锁的,但是原来不加锁的代码切成线程就很容易出原子性问题
ayanamist
2012-10-03 15:39:40 +08:00
@Js 你想多了,Python 3.2以前,GIL的粒度大的惊人,在Python内部对象里基本没有锁的问题,所以del a_dict_object[key_name]这样的是线程安全的。
Python的一个tick是很粗的,包含一个Python基本操作,例如上面那样的,连Python的一句dis都算不上。
Python的多线程编程在CPU密集应用上是会大幅度降低速度的,只适合IO密集的应用。
可以看看这两个slides
http://www.dabeaz.com/python/GIL.pdf
http://www.dabeaz.com/python/NewGIL.pdf
dingyaguang117
2013-11-08 10:04:57 +08:00
@ayanamist 似乎没有那么大粒度吧 我测试过 a+=1 这种都不是一个原子操作

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

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

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

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

© 2021 V2EX