协程
协程是程序员创造出来的不真实的一个东西
协程也可以称之为微线程,就是程序员可以人为的控制代码的运行的顺序(来回切换),其实就是对线程进行分片,使起代码来回切换
在线程中来回切换的实例
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 import greenlet 5 6 7 def testone(): 8 print(11) 9 gr2.switch() 10 print(22) 11 gr2.switch() 12 13 14 def testtwo(): 15 print(33) 16 gr1.switch() 17 print(44) 18 19 20 # 创建两个协程 21 gr1 = greenlet.greenlet(testone) 22 gr2 = greenlet.greenlet(testtwo) 23 24 gr1.switch() 25 # 单纯的协程没多大用 切换肯定还是存在时间的消耗
协程存在的意义
单纯的协程没多大用,就是遇到IO操作切换的时候就显得格外的牛逼,就有格局了
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 from gevent import monkey 5 monkey.patch_all() # 代码中遇到IO都会自动执行greenlet的switch进行切换 6 import requests 7 import gevent 8 9 10 def get_page(url): 11 ret = requests.get(url) 12 print(url, ret.content.decode('utf8')) 13 14 15 gevent.joinall([ 16 gevent.spawn(get_page, 'https://www.python.org/'), # 协程1 17 gevent.spawn(get_page, 'https://www.yahoo.com/'), # 2 18 gevent.spawn(get_page, 'https://github.com/'), # 3 19 ])
总结:**********
1.什么是协程:
称之为微线程,开发者控制线程执行流程,控制先执行某段代码然后再切换到另外的函数执行。协程本身是由程序员创造出的一个不真实存在的东西
2.协程可以提高并发吗?
协程本身是无法实现并发 协程+io切换性能就能提高
3.进程 线程 协程区别?
一个应用程序就是一块软件,一块软件中可以有多个进程,进程就是计算机分配资源的最小单元,主要用来做数据隔离,一个进程中至少存在一个线程(这个线程就是这个进程中的主线程),而线程就是CPU最小工作单元,真正用来工作的就是线程,但是呢在应用场景下:在其他语言中可能基本没咋提进程这个概念,他们基本用的线程,在python中呢有那么一说就是一般io密集型操作用多线程,计算密集型呢就用多进程,其实就是Python内部加了一把GIL锁,就是一个进程中同一时刻只允许一个线程被CPU调度,如果想利用CPU的多核优势,只能开进程,所以呢只有计算密集型才适合开进程,开多线程没用,而io密集型就要开线程,因为io操作不占CPU,程序员这个级别越来越牛逼嘛就创建了协程,这个协程本身就是不存在的东西,协程本身由程序员人为来控制代码块进行切换,本身存在没大多意义,如果协程遇到io切换了就非常牛逼了,遇到io操作就可以干其它的事情,相当于一个线程被分片了,所达到的效果就是这个线程一直没有停一直都在工作 ,这些就是这几个东西的本质上的区别,然后呢Python中协程有个greenlet模块就是可以进行代码块的切换这个模块,实现协程+io自动操作就是用的gevent这个模块,其实这个gevent这个模块也用到了greenlet这个模块,它里边有个monkey.patch_all()方法在这里就是遇到IO自动就会采用greenlet去自动的切换,gevent里边对源生的socket/select/threading/subprocess等等一些列的封装大概这三者之间的区别。想了解gevent自己看源码。
还有个简单的例子就是利用生成器关键字yield实现
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 5 def f1(): 6 print(11) 7 x1 = yield 1 8 print(x1, 22) 9 x2 = yield 2 10 print(x2, 33) 11 12 13 def f2(): 14 print(55) 15 yield 16 print(66) 17 yield 18 print(77) 19 20 21 v1 = f1() 22 v2 = f2() 23 # next(v1) 24 # v1.__next__() 25 r1 = v1.send(None) # 11 26 print(r1) # 1 27 r2 = v1.send(999) # x1=999 999 22 28 print(r2) # 2