python学习之路-协程-day10

来源:互联网 发布:nodejs json解析 编辑:程序博客网 时间:2024/06/07 06:13

大纲:
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 greenletdef test():    print(10)    g2.switch()#切换    print(23)    g2.switch()def fun():    print(46)    g1.switch()    print(89)g1=greenlet(test)#创建协程g1g2=greenlet(fun))#创建协程g2g1.switch()#跳转至协程g1#运行的结果是 10 46 23 89#从协程g1开始运行,也就是先执行test(),打印10,跳转到协程g2-fun(),打印46,重新跳转到g1-test(),打印23,跳转到协程g2-fun(),打印89from greenlet import greenletdef 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 geventdef 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 urllibimport gevent,timefrom gevent import monkeymonkey.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)

执行结果一直报错
这里写图片描述