大纲:
1.协程概念
2.yield
3.greenlet
4.gevent
5.爬虫
此章节运行环境为python27
一.协程(Coroutine)概念-又称微线程
协程可以保留上一次调用时的状态,比如:是在执行函数A时,可以随时中断,去执行函数B,然后中断继续执行函数A(可以自由切换)。协程只有一个线程执行。
二.协程应用-yield-(day04-生成器)
http://blog.csdn.net/mf_happying/article/details/76718601
三.协程应用-greenlet
greenlet和gevent必须要安装
此处在pycharm上安装–(必须提前安装easy_install,pip)
此处用的python27,python30上pip安装后一直无法使用,会继续跟进此问题
from greenlet import greenlet
def test():
print(10)
g2.switch()#切换
print(23)
g2.switch()
def fun():
print(46)
g1.switch()
print(89)
g1=greenlet(test)#创建协程g1
g2=greenlet(fun))#创建协程g2
g1.switch()#跳转至协程g1
#运行的结果是 10 46 23 89
#从协程g1开始运行,也就是先执行test(),打印10,跳转到协程g2
-fun(),打印46,重新跳转到g1-test(),打印23,跳转到协程g2
-fun(),打印89
from greenlet import greenlet
def test():
print(10)
g2.switch()#切换
print(23)
def fun():
print(46)
g1.switch()
print(89)
g1=greenlet(test)
g2=greenlet(fun)
g1.switch()
# #运行的结果是 10 46 23
#当其中一个协程结束,整个程序终止
四.协程应用–Gevent
能够自动切换任务
gevent每次遇到io操作,需要耗时等待时,会自动跳到下一个协程继续执行
import gevent
def test1():
print("-----in test1-------")
gevent.sleep(2)##用来模拟一个耗时操作,注意不是time模块中的sleep
print("-----switch1--------")
def test2():
print(".....in test2........")
gevent.sleep(2)#每当碰到耗时操作,会自动跳转至其他协程
print (".....switch2.........")
def test3():
print("//in test3")
gevent.sleep(2)
print("///switch3")
gevent.joinall([gevent.spawn(test1),gevent.spawn(test2),gevent.spawn(test3)])
#gevent.joinall相当于
#g1 = gevent.spawn(test1) # 创建一个协程
#g2 = gevent.spawn(test2)
#g3 = gevent.spawn(test3)
#g1.join() #等待协程执行结束
#g2.join()
#g3.join()
#执行结果如下
#-----in test1-------
#.....in test2........
#/in test3
#-----switch1--------
#///switch3
#.....switch2.........
五.协程-爬虫
import urllib
import gevent,time
from gevent import monkey
monkey.patch_all()#urllib遇到gevent必须打补丁,把当前所有的IO口做上标记
def f(url):
print("get:%s"%url)
response=urllib.urlopen(url)#首先是urlopen函数,用于打开一个URL
#urlopen返回一个类文件对象, 可以像文件一样操作, 同时支持一下三个方法:
#info():返回一个对象,表示远程服务器返回的头信息。
#getcode():返回Http状态码,如果是http请求,200表示请求成功完成;404表示网址未找到。
#geturl():返回请求的url地址。
data=response.read()
print("%d bytes rece from %s"%(len(data),url))
urls=["http://www.jb51.net/article/87755.htm",
"https://zhidao.baidu.com/question/1864542771987078987.html"
]
start_time=time.time()
for url in urls:
f(url)
print("cost1:",time.time()-start_time)
async_start_time=time.time()
gevent.joinall(
gevent.spawn(f("http://www.jb51.net/article/87755.htm")),
gevent.spawn(f("https://zhidao.baidu.com/question/1864542771987078987.html"))
)
print("cost2:",time.time()-async_start_time)