前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python协程

python协程

作者头像
润森
发布2019-11-10 15:39:22
4730
发布2019-11-10 15:39:22
举报
文章被收录于专栏:毛利学Python

学习一时爽,一直学习一直爽

  Hello,大家好,我是 もうり,一个从无到有的技术+语言小白。

协程是实现并发编程的一种方式。

https://docs.python.org/zh-cn/3/library/asyncio.html

一说并发,你肯定想到了多线程 / 多进程模型,没错,多线程 / 多进程,正是解决并发问题的经典模型之一

协程:是单线程下的并发,又称微线程。 英文名 Coroutine。

协程比线程的单位更小——协程

注意协程这个概念完全是程序员自己想出来的东西,它对于操作系统来说根本不存在。操作系统只知道进程和线程。

代码语言:javascript
复制
import timedef print_num(num):    print("Maoli is printing " + str(num) + " nows" )    time.sleep(1)    print("Maoli prints" + str(num) + " OK")def main(nums):    for num in nums:        print_num(num)%time main([i for i in range(1,6)])Maoli is printing 1 nowsMaoli prints1 OKMaoli is printing 2 nowsMaoli prints2 OKMaoli is printing 3 nowsMaoli prints3 OKMaoli is printing 4 nowsMaoli prints4 OKMaoli is printing 5 nowsMaoli prints5 OKWall time: 5 s

将上面代码改为协程版

注意 py 版本 3.7 以上

代码语言:javascript
复制
import asyncioasync def print_num(num):    print("Maoli is printing " + str(num) + " nows" )    await asyncio.sleep(1)    print("Maoli prints" + str(num) + " OK")async def main(nums):    for num in nums:        await print_num(num)%time asyncio.run(main([i for i in range(1,6)]))Maoli is printing 1 nowsMaoli prints1 OKMaoli is printing 2 nowsMaoli prints2 OKMaoli is printing 3 nowsMaoli prints3 OKMaoli is printing 4 nowsMaoli prints4 OKMaoli is printing 5 nowsMaoli prints5 OKWall time: 5.01 s

asyncio.run() 函数用来运行最高层级的入口点 "main()" 函数

await 是同步调用等待一个协程。以下代码段会在等待 1 秒后打印 num,

可等待对象

如果一个对象可以在 await 语句中使用,那么它就是 可等待 对象

协程中的还一个重要概念,任务(Task)

如果写一个数字是一个任务,那么毛利我要完成 5 个任务

毛利我写个 1-5 都这么慢,不行,我要加速写

asyncio.create_task() 函数用来并发运行作为 asyncio 任务 的多个协程。

代码语言:javascript
复制
import asyncioasync def print_num(num):    print("Maoli is printing " + str(num) + " nows" )    await asyncio.sleep(1)    print("Maoli prints" + str(num) + " OK")async def main(nums):    tasks = [asyncio.create_task(print_num(num)) for num in nums]    for task in tasks:        await task%time asyncio.run(main([i for i in range(1,6)]))Maoli is printing 1 nowsMaoli is printing 2 nowsMaoli is printing 3 nowsMaoli is printing 4 nowsMaoli is printing 5 nowsMaoli prints1 OKMaoli prints3 OKMaoli prints5 OKMaoli prints2 OKMaoli prints4 OKWall time: 1.01 s

还可以写成 await asyncio.gather(*tasks)这种方法

代码语言:javascript
复制
import asyncioasync def print_num(num):    print("Maoli is printing " + str(num) + " nows" )    await asyncio.sleep(1)    print("Maoli prints" + str(num) + " OK")async def main(nums):    tasks = [asyncio.create_task(print_num(num)) for num in nums]    await asyncio.gather(*tasks)%time asyncio.run(main([i for i in range(1,6)]))

*tasks 解包列表,将列表变成了函数的参数;与之对应的是, ** dict 将字典变成了函数的参数。

asyncio 队列

asyncio 队列被设计成与 queue 模块类似。

代码语言:javascript
复制
import asyncioimport randomasync def consumer(queue, id):    while True:        val = await queue.get()        print('{} get a val: {}'.format(id, val))        await asyncio.sleep(1)async def producer(queue, id):    for i in range(5):        val = random.randint(1, 10)        await queue.put(val)        print('{} put a val: {}'.format(id, val))        await asyncio.sleep(1)async def main():    # 创建队列    queue = asyncio.Queue()    # 消费者1号    consumer_1 = asyncio.create_task(consumer(queue, 'consumer_1'))    # 消费者2号    consumer_2 = asyncio.create_task(consumer(queue, 'consumer_2'))    # 生产者1号    producer_1 = asyncio.create_task(producer(queue, 'producer_1'))    # 生产者2号    producer_2 = asyncio.create_task(producer(queue, 'producer_2'))    # stop 10秒    await asyncio.sleep(10)    consumer_1.cancel()    consumer_2.cancel()    await asyncio.gather(consumer_1, consumer_2, producer_1, producer_2, return_exceptions=True)%time asyncio.run(main())

协程的写法简洁清晰,把 async / await 语法和 create_task 结合来用。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-11-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小刘IT教程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 协程是实现并发编程的一种方式。
    • 可等待对象
      • asyncio 队列
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档