python——asyncio模块实现协程、异步编程(三)
【八】协程停止
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模块实现协程、异步编程(三)相关推荐
- python——asyncio模块实现协程、异步编程(一)
我们都知道,现在的服务器开发对于IO调度的优先级控制权已经不再依靠系统,都希望采用协程的方式实现高效的并发任务,如js.lua等在异步协程方面都做的很强大. python在3.4版本也加入了协程的概念 ...
- python——asyncio模块实现协程、异步编程(二)
[六]协程并发 定义tasks时可以设置多个ensure,也可以像多线程那样用append方法实现 tasks = [asyncio.ensure_future(coroutine1),asyncio ...
- python asyncio教程_Python 协程模块 asyncio 使用指南
Python 协程模块 asyncio 使用指南 前面我们通过5 分钟入门 Python 协程了解了什么是协程,协程的优点和缺点和如何在 Python 中实现一个协程.没有看过的同学建议去看看.这篇文 ...
- Python之进程+线程+协程(异步、selectors模块、阻塞、非阻塞IO)
文章目录 一.IO多路复用 二.selectors模块 本篇文字是关于IO多路复用的更深入一步的总结,上一篇 Python之进程+线程+协程(事件驱动模型.IO多路复用.select与epoll)对I ...
- 《Python分布式计算》第2章 异步编程 (Distributed Computing with Python)
序言 第1章 并行和分布式计算介绍 第2章 异步编程 第3章 Python的并行计算 第4章 Celery分布式应用 第5章 云平台部署Python 第6章 超级计算机群使用Python 第7章 测试 ...
- 爬虫15——协程异步
1.协程,异步的概念 1.1 首先导入一段代码 import time def func():print("我爱黎明!")time.sleep(3) #睡三秒,让当前线程处于堵塞状 ...
- Python小爬虫之协程爬虫快速上手
文章目录 前言 协程 协程快速上手 协程异步运行 工作流程 任务管理 aiohttp 异步保存 异步回调 前言 爬虫是个好东西,最近要用用这玩意,所以顺便把以前的小东西给发出来,水几篇博客~ 协程 首 ...
- Python asyncio模块
文章目录 运行协程 1. asyncio.run() 源码 2. await 一个协程:同步执行 3. await 一个任务:并发执行 3.1 create_task 其他 event loop lo ...
- 线程/协程/异步的编程模型(CPU利用率为核心)
最近看了一个b站博主的视频https://www.bilibili.com/video/av64066246/讲到了线程/协程/异步的编程模型,这里做下记录 1.线程 上篇文章有聊到进程和线程的关系, ...
最新文章
- 东北大学 | 一种适用于大规模公路环境的鲁棒激光惯性里程计和建图系统
- 查询前10条_阿里开发强制要求的10条ORM映射查询规范,开发人员值得看
- java 常见数据类型
- GDCM:gdcm::Trace的测试程序
- 编程求一个后缀表达式的值
- TreeView控件二(递归算法)
- 中小企业项目的痛VS感人IT团队
- 如何隐晦地表达“滚”?
- 7500 cpuz跑分 i5_核心硬盘 i5 7500性能测试_DIY攒机酷品测试-中关村在线
- 数组元素的地址计算问题(一维到高维)
- kotlin将对象转换为map_Kotlin程序将哈希映射(HashMap)转换为列表(List)
- 【NodeJS 学习笔记02】入门资源很重要
- 一个真正成熟的人不会过度在意别人的眼光
- 【转载】NBU异机恢复oracle
- web前端性能调优(转载)
- 系统Model底层隐藏的坑
- 数据库变为可疑_SQL数据库可疑解决方法
- HTML5期末大作业:web课程设计“我的家乡”——四川成都(7页) HTML+CSS+JavaScript
- Ubuntu文件目录结构详解
- excel单元格内容拆分_Excel技巧:帮你把单元格内容颠倒顺序显示
热门文章
- java logger使用_这才是JAVA中打印日志的正确姿势
- python只能对列表进行切片_Python中的列表
- 关于fi dd ler 手机抓包 网卡地址地址_136w、136nw、138pnw 通过手机设置无线连接
- latex在overleaf可以成功编译运行,没有错误,但是上传到springer期刊的时候总是出现错误?
- vue 获取url地址的参数_Vue 网络请求框架 axios 使用教程
- 外卖餐饮点餐系统,连锁餐饮,公众号小程序源码2.1.5
- WordPress插件-Wordfence Security v7.4汉化版-可更新
- 客户关系管理系统-帮管客CRM客户管理系统 v3.0.1
- WinRAR 6.0 官方版 非常强大好用的压缩包管理器
- 百度SEO站群腾讯短网址w.url.cn生成源码|仿红源码