协程
协程
协程:
是操作系统不可见的
协程本质就是一条线程 多个任务在一条线程上来回切换
利用协程这个概念实现的内容 : 来规避IO操作,就达到了我们将一条线程中的io操作降到最低的目的
切换 并 规避io 的两个模块:
gevent = 利用了 greenlet 底层模块完成的切换 + 自动规避io的功能
asyncio = 利用了 yield 底层语法完成的切换 + 自动规避io的功能
tornado 异步的web框架
yield from - 更好的实现协程
send - 更好的实现协程
asyncio模块 基于python原生的协程的概念正式的被成立
特殊的在python中提供协程功能的关键字 : aysnc await
进程 数据隔离 数据不安全 操作系统级别 开销非常大 能利用多核
线程 数据共享 数据不安全 操作系统级别 开销小 不能利用多核 一些和文件操作相关的io只有操作系统能感知到
协程 数据共享 数据安全 用户级别 更小 不能利用多核 协程的所有的切换都基于用户,只有在用户级别能够感知到的io才会用协程模块做切换来规避(socket,请求网页的)
用户级别的协程还有什么好处:
减轻了操作系统的负担
一条线程如果开了多个协程,那么给操作系统的印象是线程很忙,这样能多争取一些时间片时间来被CPU执行,程序的效率就提高了
import gevent
def func(): # 带有io操作的内容写在函数里,然后提交func给gevent
print('start func')
gevent.sleep(1)
print('end func')
g1 = gevent.spawn(func)
g2 = gevent.spawn(func)
g3 = gevent.spawn(func)
gevent.joinall([g1,g2,g3])
# g1.join() # 阻塞 直到协程g1任务执行结束
# g2.join() # 阻塞 直到协程g1任务执行结束
# g3.join() # 阻塞 直到协程g1任务执行结束
#----------------------------------------
from gevent import monkey
monkey.patch_all()
import time
import gevent
def func(): # 带有io操作的内容写在函数里,然后提交func给gevent
print('start func')
time.sleep(1)
print('end func')
g1 = gevent.spawn(func)
g2 = gevent.spawn(func)
g3 = gevent.spawn(func)
gevent.joinall([g1,g2,g3])
asyncio模块
import asyncio
async def func(name):
print('start',name)
# await 可能会发生阻塞的方法
# await 关键字必须写在一个async函数里
await asyncio.sleep(1)
print('end')
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait([func('alex'),func('太白')]))