为了看一下goagent 的代码,需要先补一下gevent 的知识。所以在这里记录下来。
官方:http://www.gevent.org/intro.html
tutorial:http://sdiehl.github.io/gevent-tutorial/
gevent是python的一个并发框架,以微线程greenlet为核心 ,实质就是协程,资源占用少,效率高
第一个例子:
#!/usr/bin/python import gevent def foo(): print('Running in foo') gevent.sleep(0) print('Explicit context switch to foo again') def bar(): print('Explicit context to bar') gevent.sleep(0) print('Implicit context switch back to bar') gevent.joinall([gevent.spawn(foo),gevent.spawn(bar),])输出如下:
ubuntu@yee :/tmp$ python g.py
Running in foo
Explicit context to bar
Explicit context switch to foo again
Implicit context switch back to bar
例子二:
同步和异步的处理
#!/usr/bin/python #-*- coding:utf8 -*- import gevent import random def task(pid): gevent.sleep(random.randint(0,2)*0.001) print('Task',pid,'done') def synchronous(): for i in range(1,10): task(i) def asynchronous(): threads = [gevent.spawn(task,i) for i in range(1,10)] gevent.joinall(threads) print('Synchronous:') synchronous() print('Asynchronous:') asynchronous()输出结果 :
ubuntu@yee:/tmp$ python test.py Synchronous: ('Task', 1, 'done') ('Task', 2, 'done') ('Task', 3, 'done') ('Task', 4, 'done') ('Task', 5, 'done') ('Task', 6, 'done') ('Task', 7, 'done') ('Task', 8, 'done') ('Task', 9, 'done') Asynchronous: ('Task', 6, 'done') ('Task', 7, 'done') ('Task', 8, 'done') ('Task', 2, 'done') ('Task', 5, 'done') ('Task', 1, 'done') ('Task', 4, 'done') ('Task', 9, 'done') ('Task', 3, 'done')由gevent.joinall传入协程列表来初始化 greenlets,这个过程会block 当前程序,然后随机运行greenlets的列表协程。
在同步中,每个 task 都会sleep 2秒钟,整个队列下来需要花掉20秒钟。而对于异步来说,当其它task sleep的时候,其它task可以马上得到运行,2秒钟之后,所有的队列都可以运行完毕 。
所以,异步的速度相对比于同步来说更快。而需要注意的是,异步的执行顺序是不可控的。
例子三:
#!/usr/bin/python #-*- coding:utf8 -*- import gevent.monkey gevent.monkey.patch_socket() import gevent import urllib2 import time def fetch(pid): response = urllib2.urlopen('http://www.baidu.com') result = response.read() print result[:30] def synchronous(): start = time.clock() for i in range(1,30): fetch(i) end = (time.clock()-start) print("synchronous time used:",end) def asynchronous(): start = time.clock() threads = [] for i in range(1,30): threads.append(gevent.spawn(fetch,i)) gevent.joinall(threads) end = (time.clock()-start) print("asynchronous time used:",end) print 'synchronous:' synchronous() print 'asynchronous:' asynchronous()
运行的时候可以明显感觉到异步的速度更快。
=...= 原文中有有些英文比较难,就不继续了。以上学到的这些基础已经暂时够用。