python模块Asynico提供了管理事件、携程、任务和线程的功能已经编写并发代码的同步原语。

组成模块:

事件循,Asyncio 每个进程都有一个事件循环。

协程,子例程概念的泛化,可以暂停任务,等待哇爱不处理程序完成再从暂停之处返回。

Futures:定义了futures对象。

任务tasks:是Asyncio的一个子类,用于封装并管理并行模式下的协程。

管理事件循环的方法:

  1. 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()为止。
  2.  
  3. 异步调用子例程
  1. import asyncio
  2.  
  3. def fun_1(end_time,loop):
  4. print("fun1__callback")
  5.  
  6. if (loop.time() + 1.0) < end_time:
  7. loop.call_later(1,fun_2,end_time,loop)
  8. print("fun1print")
  9. else:
  10. loop.stop()
  11.  
  12. def fun_2(end_time, loop):
  13. print("fun2__callback")
  14.  
  15. if (loop.time() + 1.0) < end_time:
  16. loop.call_later(1, fun_3, end_time, loop)
  17.  
  18. else:
  19. loop.stop()
  20.  
  21. def fun_3(end_time, loop):
  22. print("fun3__callback")
  23.  
  24. if (loop.time() + 1.0) < end_time:
  25. loop.call_later(1, fun_1, end_time, loop)
  26.  
  27. else:
  28. loop.stop()
  29.  
  30. loop = asyncio.get_event_loop()
  31.  
  32. end_loop = loop.time() + 9.0
  33.  
  34. loop.call_soon(fun_1,end_loop,loop)
  35.  
  36. loop.run_forever()
  37.  
  38. loop.close()
  39.  
  40. 结果:
  41. fun1__callback
  42. fun1print
  43. fun2__callback
  44. fun3__callback
  45. fun1__callback
  46. fun1print
  47. fun2__callback
  48. fun3__callback
  49. fun1__callback
  50. fun1print
  51. fun2__callback
  52. 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退出状态机。

实现代码如下

  1. import asyncio
  2. import time
  3. from random import randint
  4.  
  5. @asyncio.coroutine
  6. def StartState():
  7. print("start state call \n")
  8. input_value = randint(0,1)
  9. time.sleep(1)
  10. if (input_value == 0):
  11. result = yield from start1(input_value)
  12. else:
  13. result = yield from start2(input_value)
  14. print("start + " + result)
  15. return result
  16. @asyncio.coroutine
  17. def start1(value):
  18. v = str(value)
  19. input_value = randint(0,1)
  20. if input_value == 0:
  21. result = yield from start2(input_value)
  22. else:
  23. result = yield from start3(input_value)
  24.  
  25. print("1 end +" + result)
  26. return v
  27.  
  28. @asyncio.coroutine
  29. def start2(value):
  30. v = str(value)
  31. input_value = randint(0, 1)
  32. if input_value == 0:
  33. result = yield from start1(input_value)
  34. else:
  35. result = yield from start3(input_value)
  36.  
  37. print("2 end +" + result)
  38. return v
  39.  
  40. @asyncio.coroutine
  41. def start3(value):
  42. v = str(value)
  43. input_value = randint(0, 1)
  44. if input_value == 0:
  45. result = yield from endy(input_value)
  46. else:
  47. result = yield from start1(input_value)
  48.  
  49. print("3 end +"+ result)
  50. return v
  51.  
  52. @asyncio.coroutine
  53. def endy(value):
  54. v = str(value)
  55. print("end +" +v )
  56. return v
  57. if __name__ == "__main__":
  58.  
  59. print("开始")
  60. loop = asyncio.get_event_loop()
  61. loop.run_until_complete(StartState())

是否切换下一个状态由input_value决定,而他是由python的random模块中的randint(0,1)函数定义的。该函数随机返回值0或1.通过这种方法,可以随机决定有限状态机被传递哪个状态。

  1. 利用Asyncio 并发协程
    Asyncio提供了一个处理任务计算的方法,asynico.Task(coroutine).该方法用于调度协程的执行,任务负责执行时间循环中的协程对象。一个事件循环只执行一个任务,也就是添加进Task中的每个任务都通过线程并发处理。
  1. import asyncio
  2.  
  3. @asyncio.coroutine
  4. def task1(number):
  5. f =
  6. for i in range(number):
  7. f += i
  8. print("task1 + %d" % i)
  9. yield from asyncio.sleep()
  10. print("task1 the end number =%d" % f)
  11.  
  12. @asyncio.coroutine
  13. def task2(number):
  14. f =
  15. for i in range(number):
  16. f *= i
  17. print("task2 * %d" % i)
  18. yield from asyncio.sleep()
  19.  
  20. print("task2 the end number = %d" % f)
  21.  
  22. @asyncio.coroutine
  23. def task3(number):
  24. f =
  25. for i in range(number):
  26. f -= i
  27. print("task2 - %d" % i)
  28. yield from asyncio.sleep()
  29.  
  30. print("task2 the end number = %d" % f)
  31.  
  32. if __name__ == "__main__":
  33. tasks = [asyncio.Task(task1()),
  34. asyncio.Task(task2()),
  35. asyncio.Task(task3())
  36. ]
  37. loop = asyncio.get_event_loop()
  38. loop.run_until_complete(asyncio.wait(tasks)) #wait 等协程结束后返回
  39. loop.close()
  40.  
  41. 输出结果:
  42. task1 +
  43. task2 *
  44. task2 -
  45. task1 +
  46. task2 *
  47. task2 -
  48. task1 +
  49. task2 *
  50. task2 -
  51. task1 +
  52. task2 *
  53. task2 -
  54. task1 +
  55. task2 *
  56. task2 -
  57. task1 +
  58. task2 *
  59. task2 -
  60. task1 +
  61. task2 *
  62. task2 -
  63. task1 +
  64. task2 *
  65. task2 -
  66. task1 +
  67. task2 *
  68. task2 -
  69. task1 +
  70. task2 *
  71. task2 -
  72. task1 the end number =
  73. task2 the end number =
  74. task2 the end number = -

使用Asyncio和Futures

  1. 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标记为已完成,并设置一个异常
  1. import asyncio
  2.  
  3. @asyncio.coroutine
  4. def firest_coroutine(future):
  5. count =
  6. for i in range():
  7. count += i
  8.  
  9. yield from asyncio.sleep()
  10. future.set_result("first corountine sum %d" % count)
  11.  
  12. @asyncio.coroutine
  13. def second_coroutine(future):
  14. count =
  15. for i in range(,):
  16. count *= i
  17.  
  18. yield from asyncio.sleep()
  19. future.set_result("second corountine sum %d" % count)
  20.  
  21. def callback_result(future):
  22. print(future.result())
  23.  
  24. if __name__ == "__main__":
  25. loop = asyncio.get_event_loop()
  26. future1 = asyncio.Future()
  27. future2 = asyncio.Future()
  28.  
  29. tasks = [
  30. firest_coroutine(future1),
  31. second_coroutine(future2)
  32. ]
  33.  
  34. future1.add_done_callback(callback_result)
  35. future2.add_done_callback(callback_result)
  36.  
  37. loop.run_until_complete(asyncio.wait(tasks))
  38. loop.close()

总结一下:主要就是通过线程和协程 实现的事件编程,通过不同事件不同状态的调用,最后这段代码主要是添加了事件中可回调对象的操作。

  1.  

python:Asyncio模块处理“事件循环”中的异步进程和并发执行任务的更多相关文章

  1. python——asyncio模块实现协程、异步编程

    我们都知道,现在的服务器开发对于IO调度的优先级控制权已经不再依靠系统,都希望采用协程的方式实现高效的并发任务,如js.lua等在异步协程方面都做的很强大. Python在3.4版本也加入了协程的概念 ...

  2. Python 协程与事件循环

    Table of Contents 前言 协程 async & await 事件循环 asyncio 的事件循环 结语 参考链接 前言 Python 标准库 asyncio 是我目前接触过的最 ...

  3. python之模块copy_reg(在python3中为copyreg,功能基本不变)

    # -*- coding: utf-8 -*-#python 27#xiaodeng#python之模块copy_reg(在python3中为copyreg,功能基本不变) import copy_r ...

  4. 简单的node爬虫练手,循环中的异步转同步

    简单的node爬虫练手,循环中的异步转同步 转载:https://blog.csdn.net/qq_24504525/article/details/77856989 看到网上一些基于node做的爬虫 ...

  5. Python进阶----计算机基础知识(操作系统多道技术),进程概念, 并发概念,并行概念,多进程实现

    Python进阶----计算机基础知识(操作系统多道技术),进程概念, 并发概念,并行概念,多进程实现 一丶进程基础知识 什么是程序: ​   程序就是一堆文件 什么是进程: ​   进程就是一个正在 ...

  6. Python asyncio 模块

    Python 3.4 asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持. asyncio的编程模型就是一个消息循环.我们从asyncio模块中直接获取一个EventLo ...

  7. Python - Asyncio模块实现的生产消费者模型

    [原创]转载请注明作者Johnthegreat和本文链接 在设计模式中,生产消费者模型占有非常重要的地位,这个模型在现实世界中也有很多有意思的对应场景,比如做包子的人和吃包子的人,当两者速度不匹配时, ...

  8. libuv事件循环中的三种句柄

    1.说明 本文会简单介绍 libuv 的事件循环,旨在入门级别的使用,而不做深入探究,简单来说就是,会大概用就行,先用熟练了,再去探究原理和源码 下图为官网的 libuv 的不同部分及其涉及的子系统的 ...

  9. for循环中进行联网请求数据、for循环中进行异步数据操作,数据排序错乱问题解决;

    for循环中进行联网请求数据,由于网络请求是异步的,第一个网络请求还没有回调,第二次第三次以及后续的网络请求又已经发出去了,有可能后续的网络请求会先回调:这时我们接收到的数据的排序就会错乱:怎么才能让 ...

随机推荐

  1. Python爬取散文网散文

    配置python 2.7 bs4 requests 安装 用pip进行安装 sudo pip install bs4 sudo pip install requests 简要说明一下bs4的使用因为是 ...

  2. <学会提问-批判性思维指南>运用

    引子 这是我第二遍读此书,我认为并且希望这次阅读对我整个人生产生深远的影响.人一出生身上带着母体的抵抗力,大概6个月以后开始渐渐消失,靠自身的抵抗力活着.30岁前很多人会带着上天给的运气,终有一天,用 ...

  3. vue移动端 实现手机左右滑动入场动画

    app.vue <template> <div id="app"> <transition :name="transitionName&qu ...

  4. [.Net Core 3.0从入门到精通]1.笔记简介及.Net Core3.0介绍

    文章目的:.Net Core 3.0学习笔记整理与分享. 面向人群:有一定基础的C#开发人员或学习人员(C#语法一定要掌握). 笔者水平:中级C#开发攻城狮(水平有限,写的不对的地方希望大家指正). ...

  5. 借助WindowBuilder插件轻松完成JAVA图形用户界面编辑

    如果以纯代码的形式进行JAVA的图形用户界面编辑,将是一件非常痛苦的事,博主在学习过程中发现了JAVA GUI编辑神器——WindowBuilder,提供可视化的编辑界面,控件的添加.排版只需使用鼠标 ...

  6. 死磕 java线程系列之线程池深入解析——普通任务执行流程

    (手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 前面我们一起学习了Java中 ...

  7. [考试反思]1003csp-s模拟测试58:沉淀

    稳住阵脚. 还可以. 至少想拿到的分都拿到了,最后一题的确因为不会按秩合并和线段树分治而想不出来. 对拍了,暴力都拍了.挺稳的. 但是其实也有波折,险些被卡内存. 如果内存使用不连续或申请的内存全部使 ...

  8. 九:写了一下红帽免费的centos6的安装步骤

    linux centos 6安装方法 前提需要: 1, centos6的镜像文件 2,VMware 提前安装 注:获取镜像 阿里开源系统,此处可下载其他的 1.Ubuntu 2.Susa 3.Cent ...

  9. UiPath之文件操作

    今天给大家介绍一下,在UiPath中如何操作文件,比如需要在某个文件夹中自动创建一个当天日期的文本. 主要使用的activity有: l  Assign l  Path Exists l  If l  ...

  10. [转载]1.1 UiPath下载安装与激活

    一.UiPath下载 1.打开官网https://www.uipath.com.cn,点击开始试用 2.选择获取UiPath社区版 3.填写姓.名.电子邮箱地址.专业领域.职位.公司.公司所在行业.国 ...