【八】协程停止

future对象有几个状态:
Pending
Running
Done
Cancelled
创建future的时候,task为pending,事件循环调用执行的时候当然就是running,调用完毕自然就是done,如果需要停止事件循环,就需要先把task取消。可以使用asyncio.Task获取事件循环的task

例如:

import asyncio
import time
now = lambda: time.time()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)
coroutine3 = do_some_work(4)tasks = [asyncio.ensure_future(coroutine1),asyncio.ensure_future(coroutine2),asyncio.ensure_future(coroutine3)
]start = now()loop = asyncio.get_event_loop()
try:loop.run_until_complete(asyncio.wait(tasks))
except KeyboardInterrupt as e:print(asyncio.Task.all_tasks())for task in asyncio.Task.all_tasks():print(task.cancel())loop.stop()loop.run_forever()
finally:loop.close()print('TIME: ', now() - start)

启动事件循环之后,马上ctrl+c,会触发run_until_complete的执行异常 KeyBorardInterrupt。然后通过循环asyncio.Task取消future

True表示cannel成功,loop stop之后还需要再次开启事件循环,最后在close,不然会报错。

循环task,逐个cancel是一种方案,可是正如上面我们把task的列表封装在main函数中,main函数外进行事件循环的调用。这个时候,main相当于最外出的一个task,那么处理包装的main函数即可。

import asyncioimport timenow = lambda: time.time()async def do_some_work(x):print('Waiting: ', x)await asyncio.sleep(x)return 'Done after {}s'.format(x)async def main():coroutine1 = do_some_work(1)coroutine2 = do_some_work(2)coroutine3 = do_some_work(4)tasks = [asyncio.ensure_future(coroutine1),asyncio.ensure_future(coroutine2),asyncio.ensure_future(coroutine3)]done, pending = await asyncio.wait(tasks)for task in done:print('Task ret: ', task.result())start = now()loop = asyncio.get_event_loop()
task = asyncio.ensure_future(main())
try:loop.run_until_complete(task)
except KeyboardInterrupt as e:print(asyncio.Task.all_tasks())print(asyncio.gather(*asyncio.Task.all_tasks()).cancel())loop.stop()loop.run_forever()
finally:loop.close()

【九】不同线程的事件循环

很多时候,我们的事件循环用于注册协程,而有的协程需要动态的添加到事件循环中。一个简单的方式就是使用多线程。当前线程创建一个事件循环,然后在新建一个线程,在新线程中启动事件循环。当前线程不会被block。

import asyncio
import time
now = lambda: time.time()
from threading import Threaddef start_loop(loop):asyncio.set_event_loop(loop)loop.run_forever()def more_work(x):print('More work {}'.format(x))time.sleep(x)print('Finished more work {}'.format(x))start = now()
new_loop = asyncio.new_event_loop()
t = Thread(target=start_loop, args=(new_loop,))
t.start()
print('TIME: {}'.format(time.time() - start))new_loop.call_soon_threadsafe(more_work, 6)
new_loop.call_soon_threadsafe(more_work, 3)

启动上述代码之后,当前线程不会被block,新线程中会按照顺序执行call_soon_threadsafe方法注册的more_work方法,后者因为time.sleep操作是同步阻塞的,因此运行完毕more_work需要大致6 + 3

【十】新线程协程

新线程协程的话,可以在主线程中创建一个new_loop,然后在另外的子线程中开启一个无限事件循环。主线程通过run_coroutine_threadsafe新注册协程对象。这样就能在子线程中进行事件循环的并发操作,同时主线程又不会被block。一共执行的时间大概在6s左右。

import asyncio
import time
now = lambda: time.time()
from threading import Threaddef start_loop(loop):asyncio.set_event_loop(loop)loop.run_forever()async def do_some_work(x):print('Waiting {}'.format(x))await asyncio.sleep(x)print('Done after {}s'.format(x))def more_work(x):print('More work {}'.format(x))time.sleep(x)print('Finished more work {}'.format(x))start = now()
new_loop = asyncio.new_event_loop()
t = Thread(target=start_loop, args=(new_loop,))
t.start()
print('TIME: {}'.format(time.time() - start))asyncio.run_coroutine_threadsafe(do_some_work(6), new_loop)
asyncio.run_coroutine_threadsafe(do_some_work(4), new_loop)

python——asyncio模块实现协程、异步编程(三)相关推荐

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

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

  2. python——asyncio模块实现协程、异步编程(二)

    [六]协程并发 定义tasks时可以设置多个ensure,也可以像多线程那样用append方法实现 tasks = [asyncio.ensure_future(coroutine1),asyncio ...

  3. python asyncio教程_Python 协程模块 asyncio 使用指南

    Python 协程模块 asyncio 使用指南 前面我们通过5 分钟入门 Python 协程了解了什么是协程,协程的优点和缺点和如何在 Python 中实现一个协程.没有看过的同学建议去看看.这篇文 ...

  4. Python之进程+线程+协程(异步、selectors模块、阻塞、非阻塞IO)

    文章目录 一.IO多路复用 二.selectors模块 本篇文字是关于IO多路复用的更深入一步的总结,上一篇 Python之进程+线程+协程(事件驱动模型.IO多路复用.select与epoll)对I ...

  5. 《Python分布式计算》第2章 异步编程 (Distributed Computing with Python)

    序言 第1章 并行和分布式计算介绍 第2章 异步编程 第3章 Python的并行计算 第4章 Celery分布式应用 第5章 云平台部署Python 第6章 超级计算机群使用Python 第7章 测试 ...

  6. 爬虫15——协程异步

    1.协程,异步的概念 1.1 首先导入一段代码 import time def func():print("我爱黎明!")time.sleep(3) #睡三秒,让当前线程处于堵塞状 ...

  7. Python小爬虫之协程爬虫快速上手

    文章目录 前言 协程 协程快速上手 协程异步运行 工作流程 任务管理 aiohttp 异步保存 异步回调 前言 爬虫是个好东西,最近要用用这玩意,所以顺便把以前的小东西给发出来,水几篇博客~ 协程 首 ...

  8. Python asyncio模块

    文章目录 运行协程 1. asyncio.run() 源码 2. await 一个协程:同步执行 3. await 一个任务:并发执行 3.1 create_task 其他 event loop lo ...

  9. 线程/协程/异步的编程模型(CPU利用率为核心)

    最近看了一个b站博主的视频https://www.bilibili.com/video/av64066246/讲到了线程/协程/异步的编程模型,这里做下记录 1.线程 上篇文章有聊到进程和线程的关系, ...

最新文章

  1. 东北大学 | 一种适用于大规模公路环境的鲁棒激光惯性里程计和建图系统
  2. 查询前10条_阿里开发强制要求的10条ORM映射查询规范,开发人员值得看
  3. java 常见数据类型
  4. GDCM:gdcm::Trace的测试程序
  5. 编程求一个后缀表达式的值
  6. TreeView控件二(递归算法)
  7. 中小企业项目的痛VS感人IT团队
  8. 如何隐晦地表达“滚”?
  9. 7500 cpuz跑分 i5_核心硬盘 i5 7500性能测试_DIY攒机酷品测试-中关村在线
  10. 数组元素的地址计算问题(一维到高维)
  11. kotlin将对象转换为map_Kotlin程序将哈希映射(HashMap)转换为列表(List)
  12. 【NodeJS 学习笔记02】入门资源很重要
  13. 一个真正成熟的人不会过度在意别人的眼光
  14. 【转载】NBU异机恢复oracle
  15. web前端性能调优(转载)
  16. 系统Model底层隐藏的坑
  17. 数据库变为可疑_SQL数据库可疑解决方法
  18. HTML5期末大作业:web课程设计“我的家乡”——四川成都(7页) HTML+CSS+JavaScript
  19. Ubuntu文件目录结构详解
  20. excel单元格内容拆分_Excel技巧:帮你把单元格内容颠倒顺序显示

热门文章

  1. java logger使用_这才是JAVA中打印日志的正确姿势
  2. python只能对列表进行切片_Python中的列表
  3. 关于fi dd ler 手机抓包 网卡地址地址_136w、136nw、138pnw 通过手机设置无线连接
  4. latex在overleaf可以成功编译运行,没有错误,但是上传到springer期刊的时候总是出现错误?
  5. vue 获取url地址的参数_Vue 网络请求框架 axios 使用教程
  6. 外卖餐饮点餐系统,连锁餐饮,公众号小程序源码2.1.5
  7. WordPress插件-Wordfence Security v7.4汉化版-可更新
  8. 客户关系管理系统-帮管客CRM客户管理系统 v3.0.1
  9. WinRAR 6.0 官方版 非常强大好用的压缩包管理器
  10. 百度SEO站群腾讯短网址w.url.cn生成源码|仿红源码