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 ...
随机推荐
- .NET MVC中的ActionResult
一 摘要 本文介绍了ASP.NET MVC中的ActionResult,本节主要介绍 EmptyResult / Content Result /JavaScriptResult /JsonResu ...
- Exception异常转String【转】
把异常的栈轨迹以String形式返回 /** * 把异常的栈轨迹以String形式返回,而不是直接打印到console * @author King * @time 2015-04-29 * @ret ...
- Study 1 —— HTML5概述
HTML5概述HTML是一种超文本标记语言,主要用于描述超文本中内容的显示方式.标记语言经过浏览器的解释和编译,虽然它本身不能显示在浏览器中,但在浏览器中可以正确显示HTML标记的内容.HTML5是一 ...
- UVALive 4725 Airport(二分)
题目链接 题意 机场有两种飞机,每小时一些飞机到达,每小时安排一架飞机起航.求任意时刻中两种飞机数目的最大值的最小值. 分析 首先肯定是二分来做.这里的难点在于如何判断飞机数目是否合法.一开始忽略了某 ...
- android数据库简单操作
1.DbOpenHelper package com.example.dbtest.dbHelper; import android.content.Context; import android.d ...
- C语言入门教程-(6)运算符
1.运算符概述 运算符是一种编译器执行特定的数学或逻辑操作的符号.C语言提供了以下类型的运算符: 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 条件运算符 其他运算符 2.算术运算符 算术 ...
- luogu P2596 [ZJOI2006]书架
传送门 感觉要死在\(Splay\)里了 orz 这题用\(Splay\)维护这个序列,其中的第\(k\)大点代表这个序列的第\(k\)个数 第一个操作,先把那个数所在的点旋到根,然后把整个根的左子树 ...
- PWA,SPA,MPA
PWA渐进式应用 特点: 不会部署到应用商店. 离线应用,通过设备进行存储规划 在发布了pwa的网站,浏览器会询问是否安装app到主屏. 方便分享,通过url. 可推送通知 . 通过service w ...
- I - Older Brother Gym - 101490I
题目链接:https://cn.vjudge.net/problem/Gym-101490I 题目大意:给你一个整数,问你这个整数能不能表示成一个素数的k次方? 具体思路:对于每一个数,我们先判断他是 ...
- python渗透
计划写一个获取qq空间加密相册的工具. 分析: 她的相册密码是手机号,先写一个生成手机号的脚本 空间有她之前的手机号,那么她现在的手机号也极有可能是一样的运营商,比如移动(缩小密码范围) 自己新建一个 ...