async/await套路编程
对于并发任务,通常是用生成消费模型,对队列的处理可以使用类似master-worker的方式,master主要用户获取队列的msg,worker用户处理消息。
为了简单起见,并且协程更适合单线程的方式,我们的主线程用来监听队列,子线程用于处理队列。这里使用redis的队列。主线程中有一个是无限循环,用户消费队列。
也即:
在主线程里,一个无限循环,一个不断加入的新任务协程:
一个loop.run_forever(),一个async def do_sleep2(x, queue, msg=""):
子线程作消费者。(代码里没有演示,只是用子线程有循环事件和异步加入协程,主线程循环结果)
import time import asyncio from queue import Queue from threading import Thread from asyncio.futures import Future from collections.abc import Coroutine, Generator """ 只要在一个生成器函数头部用上 @asyncio.coroutine 装饰器 就能将这个函数对象,【标记】为协程对象。注意这里是【标记】,划重点。 实际上,它的本质还是一个生成器。 标记后,它实际上已经可以当成协程使用。 """ @asyncio.coroutine def hello2(): yield from asyncio.sleep(1) coroutine2 = hello2() print(isinstance(coroutine2, Generator)) print(isinstance(coroutine2, Coroutine)) # True # False """ 只要在一个函数前面加上 async 关键字,这个函数对象是一个协程, 通过isinstance函数,它确实是Coroutine类型。 """ async def hello(name): print("Hello, ", name) time.sleep(2) return 'stop 2 seconds.' # 定义协程对象 coroutine = hello("world") print(isinstance(coroutine, Coroutine)) # True # 定义事件循环对象容器 loop = asyncio.get_event_loop() # 将协程转为task任务 # task = asyncio.ensure_future(coroutine) task = loop.create_task(coroutine) print(isinstance(task, Future)) # True # 将task任务扔进事件循环对象中并触发 loop.run_until_complete(task) # task.result() 可以取得返回结果 print('return value: {}'.format(task.result())) # Hello, world # return value: stop 2 seconds. # 协程函数 async def do_some_work(x): print('waiting: ', x) await asyncio.sleep(x) return 'Done after {}s'.format(x) # 协程对象 coroutine1 = do_some_work(1) coroutine2 = do_some_work(2) coroutine4 = do_some_work(4) # 将协程转成task,并组成list tasks = [ asyncio.ensure_future(coroutine1), asyncio.ensure_future(coroutine2), asyncio.ensure_future(coroutine4), ] loop = asyncio.get_event_loop() loop.run_until_complete(asyncio.wait(tasks)) # loop.run_until_complete(asyncio.gather(*tasks)) for task in tasks: print('Task ret: ', task.result()) # waiting: 1 # waiting: 2 # waiting: 4 # Task ret: Done after 1s # Task ret: Done after 2s # Task ret: Done after 4s # 外部的协程函数 async def main(): coroutine1 = do_some_work(1) coroutine2 = do_some_work(2) coroutine4 = do_some_work(4) tasks = [ asyncio.ensure_future(coroutine1), asyncio.ensure_future(coroutine2), asyncio.ensure_future(coroutine4), ] # 【重点】:await 一个task列表(协程) # dones:表示已经完成的任务 # pendings:表示未完成的任务 dones, pendings = await asyncio.wait(tasks) for task in dones: print('Task ret: ', task.result()) loop = asyncio.get_event_loop() loop.run_until_complete(main()) # waiting: 1 # waiting: 2 # waiting: 4 # Task ret: Done after 1s # Task ret: Done after 2s # Task ret: Done after 4s """ 协程中的状态 Pending:悬而未决的状态 Running:事件循环正在调用执行任务 Done:任务执行完毕 Cancelled:Task被取消后的状态 asyncio.wait:接收形式少点,控制性强,手工循环结果。 asyncio.gather:接收形式广泛,直接返回结果。 """ def start_loop(loop): # 一个在后台永远运行的事件循环 asyncio.set_event_loop(loop) loop.run_forever() def start_loop2(loop): # 一个在后台永远运行的事件循环 asyncio.set_event_loop(loop) loop.run_forever() def do_sleep(x, queue, msg=""): time.sleep(x) queue.put(msg) async def do_sleep2(x, queue, msg=""): await asyncio.sleep(x) queue.put(msg) queue = Queue() queue2 = Queue() new_loop = asyncio.new_event_loop() new_loop2 = asyncio.new_event_loop() t = Thread(target=start_loop, args=(new_loop, )) t.start() t2 = Thread(target=start_loop2, args=(new_loop2, )) t2.start() print(time.ctime()) # 动态添加两个协程 # 这种方法,在主线程是同步的 new_loop.call_soon_threadsafe(do_sleep, 6, queue, "第一个") new_loop.call_soon_threadsafe(do_sleep, 6, queue, "第二个") # 动态添加两个协程 # 这种方法,在主线程是异步的 asyncio.run_coroutine_threadsafe(do_sleep2(6, queue, "第1个"), new_loop2) asyncio.run_coroutine_threadsafe(do_sleep2(6, queue, "第2个"), new_loop2) while True: msg = queue.get() print("{} 协程运行完成。。。".format(msg)) print(time.ctime()) # Thu Dec 27 19:51:00 2018 # 第一个 协程运行完成。。。 # Thu Dec 27 19:51:06 2018 # 第二个 协程运行完成。。。 # Thu Dec 27 19:51:12 2018 while True: msg = queue2.get() print("{} 协程运行完成。。。".format(msg)) print(time.ctime()) # 第1个 协程运行完成。。。 # Thu Dec 27 20:02:10 2018 # 第2个 协程运行完成。。。 # Thu Dec 27 20:02:10 2018
async/await套路编程的更多相关文章
- 【转】C# Async/Await 异步编程中的最佳做法
Async/Await 异步编程中的最佳做法 Stephen Cleary 近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支 ...
- 【转】以Python为例的Async / Await的编程基础
转, 原文:https://www.cnblogs.com/middleware/p/11996731.html 以Python为例的Async / Await的编程基础 -------------- ...
- .NET Web应用中为什么要使用async/await异步编程
前言 什么是async/await? await和async是.NET Framework4.5框架.C#5.0语法里面出现的技术,目的是用于简化异步编程模型. async和await的关系? asy ...
- C#中 Thread,Task,Async/Await 异步编程
什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调 ...
- async/await 异步编程(转载)
转载地址:http://www.cnblogs.com/teroy/p/4015461.html 前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入 ...
- async/await 异步编程
前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入的,由于之前对于异步编程不是很了解,所以花费了一些时间学习一下相关的知识,并整理成这篇博客,如果在 ...
- c# 关于async/await异步编程的浅析和使用
线程的同步运行,时效性慢,异步运行,时效性快! 在c#5.0引出了async/await关键字,可以用其来进行异步编程. async/await定义异步方法的语法如下: 1.在方法的返回类型前面加上a ...
- .NET 中的 async/await 异步编程
原文出处: Teroy 的博客 前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入的,由于之前对于异步编程不是很了解,所以花费了一些时间学习一下相关 ...
- 以Python为例的Async / Await的编程基础
来源:Redislabs 作者:Loris Cro 翻译:Kevin (公众号:中间件小哥) 近年来,许多编程语言都在努力改进它们的并发原语.Go 语言有 goroutines,Ruby 有 fibe ...
随机推荐
- 绘图QPainter-字体
方式一: import sys from PyQt5.QtGui import QPainter, QFont,QPen from PyQt5.QtWidgets import QApplicatio ...
- [C++]指针与引用(应用辨析)
1.指针变量允许将一个整数经强制转换后赋值给指针变量 Eg: float *fp; fp = (float *)5000;//意义:将5000作为一个地址赋给指针变量fp 2 ...
- HDU2255 奔小康赚大钱 【KM算法】
题意: 每个人对不同房有不同出价,就是就是怎样匹配卖房让收入达到最大. 思路: 建立二分图,一边为N家老百姓,还有一边为N间房子.对老百姓和房子之间估价建立一条有带权边.问题就转变为了再二分图中找出一 ...
- CentOS6.8安装配置sonarqube6.4
下载最新版本的sonar(现在改名叫sonarqube) https://www.sonarqube.org/downloads/ 我下载的版本是Sonarqube6.4 1 使用前需要 ...
- bootstrap3在IE8下导航不显示,自动识别成手机模式
想让bootstrap3兼容ie8,需要将html5shiv.js.respond.js还有bootstrap的所有css.js文件都放在本地服务器空间,不能用CDN. bootstrap所有css. ...
- eclips环境下开发spring boot项目,application.properties配置文件下中文乱码解决方案
如以上,application.properties文件下中文乱码.发生乱码一般都是由于编码格式不一样导致的. 打开Window-Preferences-General-content Types-T ...
- 【Eclipse】Eclipse中打开cmd窗口和terminal窗口
在IDEA的时候可以直接使用terminal打开类似于cmd窗口的功能,于是想着在eclipse也使用类似的功能. 1.Eclipse打开类似于cmd窗口的功能.(DOS) 1.window——> ...
- weblogic基本目录介绍,位数查看,启动与发布项目,修改JVM参数,设置项目为默认项目
这里的基本目录%base%表示安装目录,如我的目录为:E:/weblogic就是%base% 1.weblogic目录介绍 weblogic主要的目录介绍: 1.日志目录: 每个domain(域)都有 ...
- CentOS 6.5下快速搭建ftp服务器[转]
CentOS 6.5下快速搭建ftp服务器 1.用root 进入系统 2.使用命令 rpm -qa|grep vsftpd 查看系统是否安装了ftp,若安装了vsftp,使用这个命令会在屏幕上显示vs ...
- Jetson tk1 安装 Intel 7260 无线网卡驱动
Jseton TK1上没有集成的无线网卡,开发板上有一个mini pci-e接口,可以插入Intel 7260这款继承了wifi和蓝牙功能的无线网卡: 该网卡实物如下图,在淘宝和Amazon上都可以买 ...