Python网络编程三:协程gevent
python的协程中要应用yield,常用于生成器:yield语句代替return返回一个值,则定义了一个生成器函数。 生成器函数使用yield语句返回一个值,然后保存当前函数整个执行状态,等待下一次调用。 在协程中使用到yield,我觉得就是利用这个特性吧。
什么是协程?
子例程的起始处是惟一的入口点,一旦退出即完成了子例程的执行,子例程的一个实例只会返回一次。 协程可以通过yield来调用其它协程。通过yield方式转移执行权的协程之间不是调用者与被调用者的关系,而是彼此对称、平等的。 协程的起始处是第一个入口点,在协程里,返回点之后是接下来的入口点。子例程的生命期遵循后进先出(最后一个被调用的子例程最先返回);相反,协程的生命期完全由他们的使用的需要决定。
含糊不清有点,看下线程和协程吧:
协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。协程和线程的区别是:协程避免了无意义的调度,由此可以提高性能,但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力。
另外直知乎上面有个答案讲了“进程、线程、协程”,参考一下:参考
好了,可以进入Gevent了。 我一开始使用Gevent只是使用“异步”,因为快! 如下代码所示:
import gevent.monkey
gevent.monkey.patch_socket()
import gevent
import requests
urls=[]
urls.append('http://myreading.sinaapp.com/yige/?offset=0')
urls.append('http://myreading.sinaapp.com/zhihu/?offset=0')
urls.append('http://myreading.sinaapp.com/meiwen/?offset=0')
urls.append('http://myreading.sinaapp.com/36kr/?offset=0')
urls.append('http://myreading.sinaapp.com/xinli/?offset=0')
urls.append('http://myreading.sinaapp.com/guokr/?offset=0')
urls.append('http://myreading.sinaapp.com/yp136/?offset=0')
def fetch(url,pid):
response = requests.get(url)
json_result = response.json()
title = json_result[0]['title']
print 'Process %s: %s' %(pid,title)
def synchronous():
for i in range(len(urls)):
fetch(urls[i],i)
def asynchronous():
threads = []
for i in range(len(urls)):
threads.append(gevent.spawn(fetch,urls[i],i))
gevent.joinall(threads)
print('Asynchronous:')
asynchronous()
print('Synchronous:')
synchronous()
关于Gevent的更多知识,以后在慢慢研究,贴个链接:Gevent指南