协程:
使用一个线程来实现异步操作的。它相对于多线程执行效率高,不存在线程切换;此外协程不牵扯多线程中锁的机制,所以不必考虑加锁这些复杂操作。
协程是通过generator来实现的,就是yield关键字和send()函数的使用。
生成器的yield关键字:
yield关键字可以将值(信息)返回,同时在信息返回后使程序停留在当前行。
>>> def test(): ... number=1 ... while True: ... number*=2 ... yield number ... print('yield下面的代码') ... >>> t=test() >>> t <generator object test at 0x000001E372BDA5F0> >>> type(t) <class 'generator'> >>> next(t) 2 >>> >>> next(t) yield下面的代码 4 >>> next(t) yield下面的代码 8 >>> next(t) yield下面的代码 16
生成器的send()函数:
yield还可以接收调用者传递过来的信息:通过sned()函数,将值(消息)传递给生成器。生成器通过yield前面的变量来接收传递过来的值。
>>> def tst(): ... number=1 ... while True: ... pam=yield number ... print('yield下面代码') ... print('调用者传递过来的值:',pam) ... >>> tt=tst() >>> tt.send(None) 1 >>> tt.send(None) yield下面代码 调用者传递过来的值: None 1 >>> tt.send(111) yield下面代码 调用者传递过来的值: 111 1
说明:send()函数和next()函数都推动生成器向下执行,next()函数仅仅是接收了yield右边的返回值;而send()函数则可以使调用者给生成器发消息。
生成器的close()函数:
调用close()函数就可以关闭生成器,接下来next()函数再应用于生成器就会提示生成器已停止的信息
>>> def test(): ... number=1 ... while True: ... number*=2 ... yield number ... print('yield下面的代码...') ... >>> gen=test() >>> next(gen) 2 >>> next(gen) yield下面的代码... 4 >>> next(gen) yield下面的代码... 8 >>> gen.close() >>> next(gen) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
协程:
通过下面一个消费者和生产者的例子,我们实现一下,生产者生产之后消费者立马消费掉,来进一步了解协程。
注意:必须在调用send()前,启动生成器。启动生成器可以是next(生成器)或者生成器.send(None),让生成器执行到第一个yield处。之后就可以不断使用send()传入值了。
def consumer(): r = '' while True: n = yield r # yield 后面的r是返回给调用者的值,yield前面的 n 用来接收调用者通过send函数传过来的值 if not n: # 如果n是None,就结束该函数,因为None代表还没有生产出来产品 print('consumer即将结束') return print('消费者正在消费%s...' % n) r = '200 OK' def produce(c): print('send返回值为: ', c.send(None)) n = 0 while n < 5: n = n + 1 print('生产者生产了%s...' % n) r = c.send(n) # 生产出来就去给消费者 print('生产者接收消费者返回的信息:%s' % r) c.close() c = consumer() produce(c)
结果:
send返回值为: 生产者生产了1... 消费者正在消费1... 生产者接收消费者返回的信息:200 OK 生产者生产了2... 消费者正在消费2... 生产者接收消费者返回的信息:200 OK 生产者生产了3... 消费者正在消费3... 生产者接收消费者返回的信息:200 OK 生产者生产了4... 消费者正在消费4... 生产者接收消费者返回的信息:200 OK 生产者生产了5... 消费者正在消费5... 生产者接收消费者返回的信息:200 OK
说明:整个过程无锁,一个线程使produce()和consumer()完成协作。
来源:https://www.cnblogs.com/bigbosscyb/p/12394744.html