学习gevent之基本用法
更新日期:
花了点时间学习gevent, 目前只了解其基本用法,但还不清楚实现原理。
一些学习资源:
- gevent site http://gevent.org/
- gevent in GitHub https://github.com/gevent/gevent
- Gevent Tutorial http://sdiehl.github.io/gevent-tutorial/
- Gevent Tutorial 中文翻译 http://xlambda.com/gevent-tutorial/
简单用法
下面的代码来自Gevent Tutorial. 首先定义两函数foo()
和bar()
来实现具体的操作,再由gevent.spawn()
创建Greenlet
对象来执行foo()
/bar()
,最后gevent.joinall()
来等待两greenlet
执行结束。foo()
/bar()
中调用gevent.sleep(0)
来显式切换到不同的Greenlet
。
|
|
要点:
- 使用
gevent.spawn()
或直接创建Greenlet
来新建执行单元 join()
函数来等待所有执行单元结束- 执行的函数里在需要等待时能切换到其它,比如
gevent.sleep(0)
, 或是网络等待事件 - Monkey patching打补丁来支持gevent, 如:
|
|
- 提供一些数据结构来支持Greenlet之间的通信,如
gevent.queue.Queue
使用gevent来实现并行查询数据
作为练习,实现的功能是手机号码归属地查询。代码仅为学习交流之用,故隐藏了查询所使用的url, 切勿用于其它目的,且本人不对使用产生的任何后果负责。
tasks = Queue()
用于存放phone number,leadWorker()
生成号码放在tasks
中,queryWorker()
从tasks
中取出一个号码查询- 查询的结果放入
resultQue = Queue()
,writeWorker()
会读取该queue的内容然后写入文件 - 1个
leadWorker()
和10个queryWorker()
同时工作
|
|
后记
尽管添加了try-catch,但在获取1万个号码地区时还是遇到了一些问题。代码运行开始时设定的worker数是10个,但在接近完成一半时发现有些worker不打印log了:第一次结尾时有5个worker打印出完成,第二次时只有一个了。可能是有等待,两次都没有正常退出,只好ctrl+c强制结束了。这是一个问题,需要解决。
后来看到有错误Connection timed out
。尽管有try-finally,但看样子是没catch住。
Traceback (most recent call last): File "/usr/local/lib/python2.7/dist-packages/gevent/greenlet.py", line 327, in run result = self._run(*self.args, **self.kwargs) File "phn.py", line 29, in queryWorker resp = urllib2.urlopen(req) File "/usr/lib/python2.7/urllib2.py", line 127, in urlopen return _opener.open(url, data, timeout) File "/usr/lib/python2.7/urllib2.py", line 404, in open response = self._open(req, data) File "/usr/lib/python2.7/urllib2.py", line 422, in _open '_open', req) File "/usr/lib/python2.7/urllib2.py", line 382, in _call_chain result = func(*args) File "/usr/lib/python2.7/urllib2.py", line 1222, in https_open return self.do_open(httplib.HTTPSConnection, req) File "/usr/lib/python2.7/urllib2.py", line 1184, in do_open raise URLError(err) URLError:failed with URLError