python之协程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python之协程相关的知识,希望对你有一定的参考价值。
协程介绍
协程:是单线程下并发,又称为微线程,纤程, 协程是一种用户状态的轻量级线程,即协程是由应用程序自己控制调度
1. python的线程属于内核级别的,即由操作系统控制调度
2.单线程内开启协程,一旦遇到io,就会从应用程序级(非系统控制)别控制切换,以此来提高效率
协程的优点:
1. 协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级
2. 单线程内就可以实现并发的效果,最大限度地利用cpu
协程的缺点:
1. 协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程
2. 协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程
协程的特点:
1.必须在只有一个单线程里实现并发
2.修改共享数据不需要加锁
3.用户程序里自己保存多个控制流的上下文栈
4.一个协程遇到io操作自动切换到其他协程
Greenlet模块
安装greenlet模块
pip install greenlet
import time def f1(): for i in range(10): time.sleep(0.5) print(\'f1>>>\',i) yield def f2(): g = f1() for i in range(10): time.sleep(0.5) print(\'f2>>\',i) next(g) f1() f2()
import time from greenlet import greenlet def f1(s): print(\'第一次f1\'+s) g2.switch(\'wusir\') #切换到g2这个对象的任务去执行 time.sleep(1) print(\'第二次f1\'+s) g2.switch() def f2(s): print(\'第一次f2\'+s) g1.switch() time.sleep(1) print(\'第二次f2\'+s) g1 = greenlet(f1) #实例化有关greenlet对象,并将任务名称为参数 g2 = greenlet(f2) g1.switch(\'alex\') #执行g1对象里面的任务
每个进程中有20个线程(5倍cpu数量),每个线程可以起500个协程,nginx在负载均衡的时候最大承载量就是5w个协程
Gevent介绍
安装gevent模块
pip install grevent
import gevent from gevent import monkey;monkey.patch_all() import time import threading def f1(): print("第一次f1") # print(threading.current_thread().getName()) # gevent.sleep(1) time.sleep(2) print("第二次f1") def f2(): # print(threading.current_thread().getName()) print(\'第一次f2\') # gevent.sleep(2) time.sleep(2) print(\'第二次f2\') s = time.time() g1 = gevent.spawn(f1)#异步提交了f1任务 g2 = gevent.spawn(f2)#异步提交了f2任务 # g1.join() # g2.join() gevent.joinall([g1,g2]) e = time.time() print(\'执行时间:\',e - s) print(\'主程序结束\')
gevent.sleep(2)模拟的是gevent认识的io阻塞
time.sleep(2) gevent是不能识别的,要识别就要在py文件的开头添加from grevent import monkey;monkey.patch_all()
以上是关于python之协程的主要内容,如果未能解决你的问题,请参考以下文章