Python学习之协程
协程,又称微线程,纤程。英文名Coroutine.
优点1:协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。
优点2:不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲实,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。
因为协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。
协程:协作式,非抢占式的程序
A--》B--》A--》C
yield()是协程的关键词
用户态的切换,关键点在于什么时候切换!
协程主要解决的也是IO操作
协程:本质上就是一个线程
协程的优势:1.没有切换的消耗 2.没有锁的概念
1 #yield的简单实现 2 import time 3 import queue 4 5 def consumer(name): 6 7 print("--->ready to eat baozi...") 8 while True: 9 new_baozi = yield 10 print("[%s] is eating baozi %s" % (name,new_baozi)) 11 #time.sleep(1) 12 13 def producer(): 14 15 r = con.__next__() 16 r = con2.__next__() 17 n = 0 18 while 1: 19 time.sleep(1) 20 print("\033[32;1m[producer]\033[0m is making baozi %s and %s" %(n,n+1) ) 21 con.send(n) 22 con2.send(n+1) 23 n +=2 24 25 if __name__ == '__main__': 26 27 con = consumer("c1") 28 con2 = consumer("c2") 29 producer() 30 ''' 31 --->ready to eat baozi... 32 --->ready to eat baozi... 33 [producer] is making baozi 0 and 1 34 [c1] is eating baozi 0 35 [c2] is eating baozi 1 36 [producer] is making baozi 2 and 3 37 [c1] is eating baozi 2 38 [c2] is eating baozi 3 39 [producer] is making baozi 4 and 5 40 [c1] is eating baozi 4 41 [c2] is eating baozi 5 42 ...... 43 ...... 44 '''
#greenlet是一个用C实现的协程模块,相比与python自带的yield,它可以使你在任意函数之间随意切换,而不需把这个函数先声明为generator from greenlet import greenlet def test1(): print(12) gr2.switch() print(34) def test2(): print(56) gr1.switch() print(78) gr1.switch() gr1 = greenlet(test1) gr2 = greenlet(test2) gr2.switch() #切换到test2 ''' 56 12 78 34 '''
gevent,是一个并发网络库。它的协程是基于greenlet的,并基于libev实现快速事件循环(Linux上是epoll,FreeBSD上是kqueue,Mac OS X上是select)。有了gevent,协程的使用将无比简单,你根本无须像greenlet一样显式的切换,每当一个协程阻塞时,程序将自动调度,gevent处理了所有的底层细节。 # 如下例子,比较串行运行时和利用协程时的执行时间,协程快一些 import gevent import requests,time start=time.time() def f(url): print('GET: %s' % url) resp =requests.get(url) data = resp.text print('%d bytes received from %s.' % (len(data), url)) # f('https://www.python.org/') # f('https://www.yahoo.com/') # f('https://www.baidu.com/') # f('https://www.sina.com.cn/') # f("http://www.xiaohuar.com/hua/") 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/'), gevent.spawn(f, 'http://www.xiaohuar.com/hua/'), ]) print("cost time:",time.time()-start) ''' GET: https://www.python.org/ 49117 bytes received from https://www.python.org/. GET: https://www.yahoo.com/ 482421 bytes received from https://www.yahoo.com/. GET: https://www.baidu.com/ 2443 bytes received from https://www.baidu.com/. GET: https://www.sina.com.cn/ 572837 bytes received from https://www.sina.com.cn/. GET: http://www.xiaohuar.com/hua/ 40320 bytes received from http://www.xiaohuar.com/hua/. cost time: 2.5858383178710938 '''
行走世间,全是妖怪

浙公网安备 33010602011771号