协程

一。定义

协程又称微线程,协程是一种用户态的轻量级的线程。

协程拥有自己的上下文和栈。协程调度切换Ⅹ,将寄存器上下文和栈保存到其它地方,再切换回来时,恢复到先前保存的寄存器上下文和栈。因此,协程能保留上一次调用的状态。

协程的好处:

  无需线程上下文切换 的开销,即协程就是一个线程。

  无需原子操作锁定及同步的开销

  方便切换控制流,简化编程模型。

  高开发,高拓展,低成,一个CPU可以支持上万的协程

二。用greenlet写协程

gr1.switch()
调用的方法
from greenlet import greenlet
def test1():
    print('12')
    gr2.switch()    #相当于yield,会停下
    print('34')
    gr2.switch()

def test2():
    print('56')
    gr1.switch()
    print('78')    
gr1=greenlet(test1)
gr2=greenlet(test2)
gr1.switch()
gr2.switch()#同时生产的相当于一个生成器,switch就像next

三。Greent是一个第三库,可以实现并发同步或异步编程

gevent.spawn(foo)调用的方法
import gevent
def foo():
    print('runing foo ')
    gevent.sleep(1)#此处不能换成time.sleep是cup内部停止运行,#gevent.sleep是io阻塞的一种模拟
    print('runing foo again')

def bar():
    print('runing bar ')
    gevent.sleep(2)
    print('runing bar again')

gevent.joinall([
    gevent.spawn(foo),
    gevent.spawn(bar)
        ])    

四.协程在爬虫方面的应用

from gevent import monkey
monkey.patch_all()    #让系统识别io阻塞
import gevent 
from urllib.request import urlopen#用于爬虫的url
import time

def f(url):
    print('get:%s'%url)
    resp=urlopen(url)#打开该网址
    data = resp.read()
    with open('python.html','wb') as f:
    
        f.write(data)
gevent.joinall([
   gevent.spawn(f,'http://www.python.org/'), 
   gevent.spawn(f,'http://www.yahoo.org/'), 
])
原文地址:https://www.cnblogs.com/gjx1212/p/12249051.html