协程,yield下支持的协程,gevent下支持的协程,简单爬虫

协程,yield下支持的协程,gevent下支持的协程,简单爬虫注:协程程序运行时间取决于其最长协程的执行时间协程:又称微线程,线程。英文名Coroutine。协程是一种用户态的轻量级线程。协程拥有本身的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其它地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。所以:协程能保留上一次调用时的状态(即全部局部状态的一个特定组成),每次过程重入时,就至关于进入上一次调用时的状态,换种说法:进入上一次离开时所在逻辑流的位置。协程的好处:(1)无需线程上下文切换的开销(2)无需原子操做锁定即同步的开销(3)方便切换控制流,简化线程模型(4)高并发+高扩展+低成本:一个cpu支持上万的协程都不是问题。因此很适合用于高并发处理。缺点:(1)没法利用多核资源:协程的本质是个单线程,他不能同时将单个cpu的多个核用上,协程须要和进程配合才能运行在多     cpu上,平常所编写的绝大部分应用都没有这个必要,除非是cpu密集型应用。(2)进行阻塞(Blocking)操做(如IO时)会阻塞掉整个程序。1.yield下支持的协程:    (1)        import time        import queue        def consumer(name):            print("   ")            while True:                new_baozi = yield                print("[%s] is eating baozi %s"%(name,new_baozi))        def producer():            r = con.__next__()            r = con2.__next__()            n=0            while n<5:                n += 1                con.send(n)                con2.send(n)                print("is making baozi %s"%n)        if __name__=='__main__':            con = consumer("c1")            con2 = consumer("c2")            p=producer()    (2)        def f():            print('ok1')            count=yield 5            print(count)            print('ok2')            yield 6        # print(f())#<generator object f at 0x00000164C3A8F4F8>        gen=f()        # ret=next(gen)#生成器        # print(ret)        ret = gen.send(None)#注:第一次send的时候是找不到目标的,要有一次yield折回        print(ret)        x=gen.send(8)        print(x)2.gevent下支持的协程:        #author: wylkjj        #date:2019/5/13        from greenlet import greenlet        def test1():            print(12)            gr2.switch()#切换            print(34)            gr2.switch()#切换        def test2():            print(56)            gr1.switch()#切换            print(78)        gr1 = greenlet(test1)#建立对象        # print(gr1)        gr2 = greenlet(test2)#建立对象        gr1.switch()#调用执行  结果:12 56 34 78        简单协程实例:        import gevent        def foo():            print('Running in foo')            gevent.sleep(0)#模拟IO阻塞            print('Explicit context switch to foo again')        def bar():            print('Explicit context to bar')            gevent.sleep(0)#模拟IO阻塞            print('Implicit switch back bar')        gevent.joinall([            gevent.spawn(foo),            gevent.spawn(bar),        ])3.简单爬虫:    (1)爬取网页并写到文件里面        from urllib.request import urlopen        def f(url):            print('GET:%s'%url)            resp = urlopen(url)            data = resp.read()            with open('bilibili.html','wb')as f:                f.write(data)            print('%d bytes received from %s.'%(len(data),url))        f('https://www.bilibili.com/')    (2)爬取网页        #author: wylkjj        #date:2019/5/14        import gevent,time        from gevent import monkey #对IO流监控增强控制        monkey.patch_all()        from urllib.request import urlopen        def f(url):            print('GET:%s'%url)            resp = urlopen(url)            data = resp.read()            # with open('bilibili.html','wb')as f:            #     f.write(data)            print('%d bytes received from %s.'%(len(data),url))        # f('https://www.bilibili.com/')        # list = ['https://www.python.org/','https://www.yahoo.com/','https://github.com/']        start=time.time()        # for url in list:        #     f(url)#8.78313660621643秒        gevent.joinall([ #时间3.7336878776550293秒 协程节省时间            gevent.spawn(f,'https://www.python.org/'),            gevent.spawn(f,'https://www.yahoo.com/'),            gevent.spawn(f,'https://github.com/'),        ])        print(time.time()-start)
相关文章
相关标签/搜索