Python多线程开发--协程
协程协程(coroutine),又称为微线程,纤程。(协程是一种用户态的轻量级线程)作用:在执行A 函数的时候,可以随时中断,去执行B 函数,然后中断继续执行A 函数(可以自动切换),注意这一过程并不是函数调用(没有调用语句),过程很像多线程,然而协程只有一个线程在执行协作的标准1.必须在只有一个单线程里实现并发2.修改共享数据不需加锁3.用户程序里自己保存多个控制流的上下文栈4.一个协程遇到IO
协程
协程(coroutine),又称为微线程,纤程。(协程是一种用户态的轻量级线程)
作用:在执行A 函数的时候,可以随时中断,去执行B 函数,然后中断继续执行A 函数(可以自动切换),注意这一过程并不是函数调用(没有调用语句),过程很像多线程,然而协程只有一个线程在执行
协作的标准
1.必须在只有一个单线程里实现并发
2.修改共享数据不需加锁
3.用户程序里自己保存多个控制流的上下文栈
4.一个协程遇到IO 操作自动切换到其它协程
协程创建方式1:
通过greenlet模块
from greenlet import greenlet
def sleep(name):
print(f"{name}开始睡觉了...")
g2.switch('曹操')
print(f"{name}起床了...")
g2.switch()
def eat(name):
print(f"{name}开始吃饭了...")
g1.switch()
print(f"{name}吃完了...")
if __name__ == '__main__':
g1 = greenlet(sleep)
g2 = greenlet(eat)
g1.switch('小乔')
小乔开始睡觉了...
曹操开始吃饭了...
小乔起床了...
曹操吃完了...
2.通过gevent模块
Gevent 是一个第三方库,可以轻松通过gevent 实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet,它是以C 扩展模块形式接入Python 的轻量级协程。Greenlet 全部运行在主程序操作系统进程的内部,但他们被协作式地调度。
当一个greenlet遇到IO操作时,比如访问网络/睡眠等待,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。同时也因为只有一个线程在执行,会极大的减少上下文切换的成本
import gevent
def sleep(name):
print(f"{name}开始睡觉了...")
gevent.sleep(1)
print(f"{name}起床了...")
def eat(name):
print(f"{name}开始吃饭了...")
gevent.sleep(1)
print(f"{name}吃完了...")
if __name__ == '__main__':
g1=gevent.spawn(sleep, '小乔')
g2=gevent.spawn(eat, '曹操')
gevent.joinall([g1,g2])
小乔开始睡觉了...
曹操开始吃饭了...
小乔起床了...
曹操吃完了...
3.通过asyncio模块
import asyncio,time
async def fun1():
for i in range(5):
print("协程1")
await asyncio.sleep(1)
# await 后跟一个可等待的对象
async def fun2():
for i in range(5):
print("携程2")
await asyncio.sleep(2)
if __name__ == '__main__':
start=time.time()
asy_a = fun1()
asy_b = fun2()
#获取循环事件
loop = asyncio.get_event_loop()
#监听循环事件
loop.run_until_complete(asyncio.gather(asy_a, asy_b))
#关闭循环
loop.close()
end=time.time()
print(f"总用时:{end-start}s")
协程1
携程2
协程1
携程2
协程1
协程1
携程2
协程1
携程2
携程2
总用时:10.010684967041016s
协程的嵌套:使用async可以定义协程,协程用于耗时的io操作,我们也可以封装更多的io操作过程,这样就实现了嵌套的协程,即一个协程中await了另外一个协程,如此连接起来。
import asyncio
import time
async def seed_to(x, y):
print("老王你帮我算一下结果")
result = await lao_w(x, y)
print(f"结果为:{result}")
async def lao_w(x, y):
print("好的,稍等一下")
await asyncio.sleep(1)
return x + y
if __name__ == '__main__':
start=time.time()
loop = asyncio.get_event_loop()
loop.run_until_complete(seed_to(6, 8))
loop.close()
end=time.time()
print(f"耗时:{end-start}s")
老王你帮我算一下结果
好的,稍等一下
结果为:14
耗时:1.0017786026000977s
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)