python:Asyncio模块处理“事件循环”中的异步进程和并发执行任务
python模块Asynico提供了管理事件、携程、任务和线程的功能已经编写并发代码的同步原语。
组成模块:
事件循,Asyncio 每个进程都有一个事件循环。
协程,子例程概念的泛化,可以暂停任务,等待哇爱不处理程序完成再从暂停之处返回。
Futures:定义了futures对象。
任务tasks:是Asyncio的一个子类,用于封装并管理并行模式下的协程。
管理事件循环的方法:
loop = asyncio.get_event_loop() 获得当前上下文事件循环
loop.call_later(time_delay,caallback,argument) 在给定时间time_delay秒后,调用某个回调对象。
loop.call_soon(callback,argument) 该方法马上安排一个被调用的回调对象。
loop.time() 以浮点数形式返回根据事件循环的内部时钟确定的当前时间。
asyncio.set_event_loop() 将当前上下文的时间循环设置为3给定循环。
asyncio.new_event_loop() 根据此函数的规则创建并返回一个新的时间循环对象。
loop.run_forever() 一直执行知道调用stop()为止。 异步调用子例程
import asyncio def fun_1(end_time,loop):
print("fun1__callback") if (loop.time() + 1.0) < end_time:
loop.call_later(1,fun_2,end_time,loop)
print("fun1print")
else:
loop.stop() def fun_2(end_time, loop):
print("fun2__callback") if (loop.time() + 1.0) < end_time:
loop.call_later(1, fun_3, end_time, loop) else:
loop.stop() def fun_3(end_time, loop):
print("fun3__callback") if (loop.time() + 1.0) < end_time:
loop.call_later(1, fun_1, end_time, loop) else:
loop.stop() loop = asyncio.get_event_loop() end_loop = loop.time() + 9.0 loop.call_soon(fun_1,end_loop,loop) loop.run_forever() loop.close() 结果:
fun1__callback
fun1print
fun2__callback
fun3__callback
fun1__callback
fun1print
fun2__callback
fun3__callback
fun1__callback
fun1print
fun2__callback
fun3__callback
从输出结果上我们可以看到这个任务调用是完全异步的,开始loop.call_soon(fun_1,end_loop,loop) 立刻调用fun_1 当if条件成立时延迟一秒执行fun_2 但是fun_1的下一句print依然直接输出。但是我后来又测试他实际上还是要等fun_1里的其他语句执行完才会切换到fun_2。
总结:只是在fun_1 1S后调用fun_2期间他会执行fun_1中的其他语句,但是如果需要的时间过长就会等待fun_1所有语句执行完毕才会切换到fun_2不仅仅等一秒。
使用Asyncio处理协程
与子例程相似但是不存在用于协调结果的主程序,协程之间可以相互连接形成一个管道,不需要任何监督函数来按顺序调用协程。谢承忠可以暂停执行,同时保存干预时的本地状态,便于后续继续执行任务。有了协程池,协程计算就能够相互交错。
特点:
协程支持多个进入点,可以多次生成。
协程能够将执行转移至任意其他协程。
下方实现了一个有限状态机。
如图:系统有5个状态 ,start 、s1、s2、s3、end
这里s1-s3是自动循环切换。开始通过start进入状态机从end退出状态机。
实现代码如下
import asyncio
import time
from random import randint @asyncio.coroutine
def StartState():
print("start state call \n")
input_value = randint(0,1)
time.sleep(1)
if (input_value == 0):
result = yield from start1(input_value)
else:
result = yield from start2(input_value)
print("start + " + result)
return result
@asyncio.coroutine
def start1(value):
v = str(value)
input_value = randint(0,1)
if input_value == 0:
result = yield from start2(input_value)
else:
result = yield from start3(input_value) print("1 end +" + result)
return v @asyncio.coroutine
def start2(value):
v = str(value)
input_value = randint(0, 1)
if input_value == 0:
result = yield from start1(input_value)
else:
result = yield from start3(input_value) print("2 end +" + result)
return v @asyncio.coroutine
def start3(value):
v = str(value)
input_value = randint(0, 1)
if input_value == 0:
result = yield from endy(input_value)
else:
result = yield from start1(input_value) print("3 end +"+ result)
return v @asyncio.coroutine
def endy(value):
v = str(value)
print("end +" +v )
return v
if __name__ == "__main__": print("开始")
loop = asyncio.get_event_loop()
loop.run_until_complete(StartState())
是否切换下一个状态由input_value决定,而他是由python的random模块中的randint(0,1)函数定义的。该函数随机返回值0或1.通过这种方法,可以随机决定有限状态机被传递哪个状态。
利用Asyncio 并发协程
Asyncio提供了一个处理任务计算的方法,asynico.Task(coroutine).该方法用于调度协程的执行,任务负责执行时间循环中的协程对象。一个事件循环只执行一个任务,也就是添加进Task中的每个任务都通过线程并发处理。
import asyncio @asyncio.coroutine
def task1(number):
f =
for i in range(number):
f += i
print("task1 + %d" % i)
yield from asyncio.sleep()
print("task1 the end number =%d" % f) @asyncio.coroutine
def task2(number):
f =
for i in range(number):
f *= i
print("task2 * %d" % i)
yield from asyncio.sleep() print("task2 the end number = %d" % f) @asyncio.coroutine
def task3(number):
f =
for i in range(number):
f -= i
print("task2 - %d" % i)
yield from asyncio.sleep() print("task2 the end number = %d" % f) if __name__ == "__main__":
tasks = [asyncio.Task(task1()),
asyncio.Task(task2()),
asyncio.Task(task3())
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks)) #wait 等协程结束后返回
loop.close() 输出结果:
task1 +
task2 *
task2 -
task1 +
task2 *
task2 -
task1 +
task2 *
task2 -
task1 +
task2 *
task2 -
task1 +
task2 *
task2 -
task1 +
task2 *
task2 -
task1 +
task2 *
task2 -
task1 +
task2 *
task2 -
task1 +
task2 *
task2 -
task1 +
task2 *
task2 -
task1 the end number =
task2 the end number =
task2 the end number = -
使用Asyncio和Futures
future = asyncio.Future()
future.cancel() 取消future,并安排回调函数。
future.result() 返回future锁代表的结果
future.exception() 返回fture上设置的异常
future.add_done_callback() 添加一个在future执行时运行的回调函数
future.remove_done_callback() 从借宿后调用列表中溢出一个回调对象的所有实例
future.set_result() 将future标记为已完成并设置其结果
future.set_exception() 将future标记为已完成,并设置一个异常
import asyncio @asyncio.coroutine
def firest_coroutine(future):
count =
for i in range():
count += i yield from asyncio.sleep()
future.set_result("first corountine sum %d" % count) @asyncio.coroutine
def second_coroutine(future):
count =
for i in range(,):
count *= i yield from asyncio.sleep()
future.set_result("second corountine sum %d" % count) def callback_result(future):
print(future.result()) if __name__ == "__main__":
loop = asyncio.get_event_loop()
future1 = asyncio.Future()
future2 = asyncio.Future() tasks = [
firest_coroutine(future1),
second_coroutine(future2)
] future1.add_done_callback(callback_result)
future2.add_done_callback(callback_result) loop.run_until_complete(asyncio.wait(tasks))
loop.close()
总结一下:主要就是通过线程和协程 实现的事件编程,通过不同事件不同状态的调用,最后这段代码主要是添加了事件中可回调对象的操作。
python:Asyncio模块处理“事件循环”中的异步进程和并发执行任务的更多相关文章
- python——asyncio模块实现协程、异步编程
我们都知道,现在的服务器开发对于IO调度的优先级控制权已经不再依靠系统,都希望采用协程的方式实现高效的并发任务,如js.lua等在异步协程方面都做的很强大. Python在3.4版本也加入了协程的概念 ...
- Python 协程与事件循环
Table of Contents 前言 协程 async & await 事件循环 asyncio 的事件循环 结语 参考链接 前言 Python 标准库 asyncio 是我目前接触过的最 ...
- python之模块copy_reg(在python3中为copyreg,功能基本不变)
# -*- coding: utf-8 -*-#python 27#xiaodeng#python之模块copy_reg(在python3中为copyreg,功能基本不变) import copy_r ...
- 简单的node爬虫练手,循环中的异步转同步
简单的node爬虫练手,循环中的异步转同步 转载:https://blog.csdn.net/qq_24504525/article/details/77856989 看到网上一些基于node做的爬虫 ...
- Python进阶----计算机基础知识(操作系统多道技术),进程概念, 并发概念,并行概念,多进程实现
Python进阶----计算机基础知识(操作系统多道技术),进程概念, 并发概念,并行概念,多进程实现 一丶进程基础知识 什么是程序: 程序就是一堆文件 什么是进程: 进程就是一个正在 ...
- Python asyncio 模块
Python 3.4 asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持. asyncio的编程模型就是一个消息循环.我们从asyncio模块中直接获取一个EventLo ...
- Python - Asyncio模块实现的生产消费者模型
[原创]转载请注明作者Johnthegreat和本文链接 在设计模式中,生产消费者模型占有非常重要的地位,这个模型在现实世界中也有很多有意思的对应场景,比如做包子的人和吃包子的人,当两者速度不匹配时, ...
- libuv事件循环中的三种句柄
1.说明 本文会简单介绍 libuv 的事件循环,旨在入门级别的使用,而不做深入探究,简单来说就是,会大概用就行,先用熟练了,再去探究原理和源码 下图为官网的 libuv 的不同部分及其涉及的子系统的 ...
- for循环中进行联网请求数据、for循环中进行异步数据操作,数据排序错乱问题解决;
for循环中进行联网请求数据,由于网络请求是异步的,第一个网络请求还没有回调,第二次第三次以及后续的网络请求又已经发出去了,有可能后续的网络请求会先回调:这时我们接收到的数据的排序就会错乱:怎么才能让 ...
随机推荐
- springMVC初学简单例子
新建web项目,保留web.xml. 配置web.xml文件(/WEB-INF/下): <?xml version="1.0" encoding="UTF-8&qu ...
- 时序数据库InfluxDB(I)- 搭建与采集信息demo操作
搭建环境:vmware workstation pro15.5.0, ubuntu18.04.3 实践时间:2019.10.12-10.27 (一)时序数据库InfluxDB准备 (1)安装 曾出现问 ...
- LeetCode 5024 除数博弈 --(简单博弈论)
今天在LeetCode的看到一到题目 这道题目有点坑,没有思路的话容易钻牛角. 刚刚开始时,我想的是直接用while循环来模拟计算,后来觉得这么好麻烦,也有复制的逻辑在里面.后面我推导了一下 以下是我 ...
- SpringMVC重点知识总结
SpringMVC总结 1. SpringMVC简介 MVC即模型-视图-控制器(Model-View-Controller) Spring Web MVC是一种基于Java的实现了Web MVC设计 ...
- 机器学习回顾篇(8):CART决策树算法
1 引言 上一篇博客中介绍了ID3和C4.5两种决策树算法,这两种决策树都只能用于分类问题,而本文要说的CART(classification and regression tree)决策树不仅能用于 ...
- printf 格式输出代码大全
d,lx,ld,,lu,这几个都是输出32位的hd,hx,hu,这几个都是输出16位数据的,hhd,hhx,hhu,这几个都是输出8位的,lld,ll,llu,llx,这几个都是输出64位的, pri ...
- OptimalSolution(2)--二叉树问题(4)子树与拓扑结构
一.判断t1树是否包含t2树全部的拓扑结构 1 / \ 2 3 2 / \ / \ / \ 4 5 6 7 4 5 / \ / / 8 9 10 8 返回:true 解法(O(M×N)):如果t1中某 ...
- 如何把当前时间戳转化为时间格式HH:MM:SS
获取当前时间戳 var timestamp = new Date().getTime() 获取当前时间(从1970.1.1开始的毫秒数) // 创建一个函数function timestampToTi ...
- 你编写的Java代码是咋跑起来的?
如果你是一名 Java 开发人员,你肯定指定 Java 代码有很多种不同的运行方式.比如说可以在开发工具(IDEA.Eclipse等)中运行,可以双击执行 jar 文件运行,也可以在命令行中运行,甚至 ...
- 设计时需要考虑的问题(webAPI)
1.根据api接口访问路径定义好controller和action. 2.记录操作日志.包含接口入参.出参.异常以及重要的节点数据(数据库返回.第三方接口返回.重要的私有变量值) 3.入参合法性检查. ...