python协程

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

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

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

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

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

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

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

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

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 以上

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 任务 的多个协程。

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)这种方法

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 模块类似。

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 结合来用。

本文分享自微信公众号 - 毛利学Python(sen13717378202)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏成猿之路

SpringBoot+Mybatis+Swagger2环境搭建

SpringBoot相对于传统的SSM框架的优点是提供了默认的样板化配置,简化了Spring应用的初始搭建过程,如果你不想被众多的xml配置文件困扰,可以考虑使...

12410
来自专栏绿盟科技安全情报

【漏洞预警】Weblogic反序列化远程代码执行漏洞预警通告

4月17日,国家信息安全漏洞共享平台(CNVD)公开了Weblogic反序列化远程代码执行漏洞,此漏洞存在于weblogic自带的wls9_async_resp...

10410
来自专栏数据猿

什么将会替代 JavaScript 呢?

JavaScript 正在蓬勃发展。但由于 WebAssembly 的出现,它的衰落可能只是一个时间问题。

11220
来自专栏JAVA杂谈

Java日志Log4j或者Logback的NDC和MDC功能

Java中使用的日志的实现框架有很多种,常用的log4j和logback以及java.util.logging,而log4j是apache实现的一个开源日志组件...

15120
来自专栏绿盟科技安全情报

【漏洞预警】Weblogic wls9-async反序列化远程代码执行漏洞预警通告V2.0

4月17日,国家信息安全漏洞共享平台(CNVD)公开了Weblogic反序列化远程代码执行漏洞(CNVD-C-2019-48814),此漏洞存在于weblogi...

9130
来自专栏Java3y

网络协议常见面试题

答:Http协议运行在TCP之上,明文传输,客户端与服务器端都无法验证对方的身份;Https是身披SSL(Secure Socket Layer)外壳的Http...

15570
来自专栏深圳java培训

深圳Web前端学习:js中的模块化--【千锋】

我们知道最常见的模块化方案有CommonJS、AMD、CMD、ES6,AMD规范一般用于浏览器,异步的,因为模块加载是异步的,js解释是同步的,所以有时候导致依...

9830
来自专栏一Li小麦

JavaScript设计模式之策略模式

为达到一个目的做事情的方法有很多种,比如做工资表,需要计算码农,美工,需求三个人的工资。这时候如果是一个靠谱的人事,一定会有这样一个表:

7810
来自专栏蚂蚁开源社区

支持animate.css动画的jquery弹出层特效

jquery.popup.js是一款支持animate.css动画效果的弹出层模态窗口插件。你可以在初始化插件时,配置模态窗口打开和关闭时的CSS3,使用非常炫...

19450
来自专栏绿盟科技安全情报

【漏洞预警】Weblogic反序列化漏洞(绕过CVE-2019-2725)0day预警通告

近日,绿盟科技安全团队发现针对Oracle Weblogic的在野漏洞利用,攻击特征与CVE-2019-2725类似。此攻击可以绕过Oracle官方在4月份发布...

10420

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励