前言
为了看一下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()
运行的时候可以明显感觉到异步的速度更快。
=...= 原文中有有些英文比较难,就不继续了。以上学到的这些基础已经暂时够用。