Python3基础-协程
-
协程
协程,又称微线程,纤程。英文名Coroutine。 非抢占式的程序
A-->B-->A--》B
协程主要解决的就是IO操作的
协程:本质上就是一个线程
协程的优势:
1、没有切换的消耗
2、没有锁的概念
优点1: 协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。
优点2: 不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。
因为协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。
-
协程的关键词 ---》yield的实现
yield首先是个return,普通的return是什么意思,就是在程序中返回某个值,返回之后程序就不再往下运行了。看做return之后再把它看做一个是生成器(generator)的一部分(带yield的函数才是真正的迭代器)
def foo(): print("string.....") while True: res = yield 4 print("res:",res) g = foo() print(next(g)) print("*"*20) print(g.send(7))
执行结果如下:
string..... 4 ******************** res: 7 4
这就结束了,说一下,为什么用这个生成器,是因为如果用List的话,会占用更大的空间,比如说取0,1,2,3,4,5,6............1000
你可能会这样:
for n in range(1000): a=n
这个时候range(1000)就默认生成一个含有1000个数的list了,所以很占内存。
这个时候你可以用刚才的yield组合成生成器进行实现,也可以用xrange(1000)这个生成器实现
yield组合:
def foo(num): print("starting.....") while num < 10: num = num + 1 yield num for n in foo(0): print(n)
以上结果如下:
starting.....
1
2
3
4
5
6
7
8
9
10
yield的简单实现
import time import queue def consumer(name): print("--->ready to eat baozi...") while True: new_baozi = yield print("[%s] is eating baozi %s" % (name,new_baozi)) #time.sleep(1) def producer(): r = con.__next__() r = con2.__next__() n = 1 while 1: time.sleep(1) print("\033[32;1m[producer]\033[0m is making baozi %s and %s" %(n,n+1) ) con.send(n) con2.send(n+1) n +=2 if __name__ == '__main__': con = consumer("c1") con2 = consumer("c2") p = producer()
结果如下:
--->ready to eat baozi... --->ready to eat baozi... [producer] is making baozi 1 and 2 [c1] is eating baozi 1 [c2] is eating baozi 2 [producer] is making baozi 3 and 4 [c1] is eating baozi 3 [c2] is eating baozi 4 [producer] is making baozi 5 and 6 [c1] is eating baozi 5 [c2] is eating baozi 6 [producer] is making baozi 7 and 8 [c1] is eating baozi 7 [c2] is eating baozi 8 [producer] is making baozi 9 and 10 [c1] is eating baozi 9 [c2] is eating baozi 10
Greenlet
greenlet是一个用C实现的协程模块,相比与python自带的yield,它可以使你在任意函数之间随意切换,而不需把这个函数先声明为generator
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) gr2 = greenlet(test2) gr1.switch()
执行结果如下:
12 56 34 78
Gevent
import gevent import requests,time start=time.time() def f(url): print('GET: %s' % url) resp =requests.get(url) data = resp.text f = open("new","w",encoding="utf-8") f.write(data) print('%d bytes received from %s.'%(len(data), url)) gevent.joinall([ gevent.spawn(f, 'https://www.python.org/'), # # 创建一个协程 # gevent.spawn(f, 'https://www.yahoo.com/'), gevent.spawn(f, 'https://www.baidu.com/'), gevent.spawn(f, 'https://www.sina.com.cn/'), ]) # # f('https://www.python.org/') # f('https://baidu.com/') # f('https://www.sina.com.cn/') print("cost time:",time.time()-start)
https://www.cnblogs.com/yuanchenqi/acticles/6248025.html
浙公网安备 33010602011771号