python异步编程案例之协程执行和停止
执行协程
asyncio提供了三种执行协程的机制
- 使用asyncio.run()执行协程(仅限于python3.7以上版本)。此函数总是创建一个新的事件循环,并在最后关闭它。建议将它用作asyncio程序的主入口,如main(),并且只调用一次。在同一个线程中,当已经有asyncio事件循环在执行时,不能调用此函数。
- await一个协程。在一个已经运行协程中await另一协程。
import asyncioasync def do_some_work(x):print("Hello:", x)return "work is done for {}".format(x)# async def main():
# tasks = []
# for i in range(5):
# tasks.append(asyncio.ensure_future(do_some_work(i)))
# return await asyncio.gather(*tasks)async def main():for i in range(5):result = await do_some_work(i)print(result)
asyncio.run(main())
Hello: 0
work is done for 0
Hello: 1
work is done for 1
Hello: 2
work is done for 2
Hello: 3
work is done for 3
Hello: 4
work is done for 4
之前使用的是python 3.6版本,可以在外部直接await
await main()
Hello: 0
Hello: 1
Hello: 2
Hello: 3
Hello: 4
Out[34]:
['work is done for 0','work is done for 1','work is done for 2','work is done for 3','work is done for 4']
但是在3.7里,就报错。。。
await main()
File "<input>", line 14
SyntaxError: 'await' outside function
- 定义一个事件循环对象loop容器,将task任务扔进事件循环对象中触发。把协程对象交给 loop,协程对象随后会在 loop 里得到运行。
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(main())
Hello: 0
work is done for 0
Hello: 1
work is done for 1
Hello: 2
work is done for 2
Hello: 3
work is done for 3
Hello: 4
work is done for 4
停止协程
loop启动之后,ctrl+c,run_until_complete会有执行异常。通过asyncio.Task的cancel方法可以取消future。
调用cancel()会引起Task对象向被封装的协程抛出CancelledError异常。当取消行为发生时,如果协程正在等待某个Future对象执行,该Future对象将被取消。
cancelled()方法用于检查某个Task是否已被取消。如果Task封装的协程没有阻止CancelledError异常,且Task确实被取消了,则该方法返回True。
import asyncio
import timeasync def do_some_work(x):print('Hello do_some_work:', x)try:await asyncio.sleep(x)except asyncio.CancelledError:print('task do_some_work({}) was canceled'.format(x))raise # 这里不raise的话,程序会继续,task 仍然是active(这是try, except特征决定的)print('do_some_work({}) is still active'.format(x))# 如果这句话被打印,证明task仍是activereturn "work is done for {}".format(x)def cancel_task(future):future.cancel()print('cancelled the task:', id(future))async def main(loop):tasks = []for i in range(5):coroutine = do_some_work(i)# task = asyncio.ensure_future(coroutine)task = loop.create_task(coroutine)tasks.append(task)# loop.call_soon(cancel_task, task)return await asyncio.gather(*tasks)print('start...')
start = time.time()
event_loop = asyncio.new_event_loop()
asyncio.set_event_loop(event_loop)
try:results = event_loop.run_until_complete(main(event_loop))for result in results:print("task result:", result)
except KeyboardInterrupt:now = event_loop.time()# print(asyncio.Task.all_tasks())for task in asyncio.Task.all_tasks():print('cancelling the task {}: {}'.format(id(task), task.cancel()))# event_loop.call_soon(cancel_task, task)event_loop.stop()event_loop.run_forever() # restart loop
finally:event_loop.close()
end = time.time()
print("total run time: ", end - start)
start...
Hello do_some_work: 0
Hello do_some_work: 1
Hello do_some_work: 2
Hello do_some_work: 3
Hello do_some_work: 4
do_some_work(0) is still active
do_some_work(1) is still active
^Ccancelling the task 2246916857928: True
cancelling the task 2246916861192: True
cancelling the task 2246916858200: False
cancelling the task 2246916860240: True
cancelling the task 2246916861328: True
cancelling the task 2246916860376: False
task do_some_work(2) was canceled
task do_some_work(3) was canceled
task do_some_work(4) was canceled
total run time: 2.0016472339630127
True 表示 cancel 成功。运行程序,不到一秒的时间立马就ctr+c。以上看出 do_some_work(0) 没有cancel成功,因为asyncio.sleep(0) 也就是没有sleep, 所以do_some_work(0)瞬间就完成了,这时候取消为时已晚,其他没有来得及执行的task都成功取消了。
shield
如果一个创建后就不希望被任何情况取消,可以使用asyncio.shield保护任务能顺利完成。
shield方法可以将协程(coroutines),该对象会被自动封装为Task。
python异步编程案例之协程执行和停止相关推荐
- python生成器单线程_「Python异步编程-3」协程、生成器、yield 的联系
异步编程的基础在于理解协程,而协程的基础在于理解生成器,而生成器的基础在于理解yield关键字,下面就来说说这几个概念. 什么是yield关键字? 相当于return关键字,在每次next(),或者f ...
- python异步编程案例之Future和Task
Future,是对协程的封装,代表一个异步操作的最终结果,其值会在将来被计算出来.当一个Future对象被await的时候,表示当前的协程会持续等待,直到 Future对象所指向的异步操作执行完毕.日 ...
- Python——异步编程案例
摘要 主要是讲解Python中的异步编程的下的实际的案例 案例:异步操作redis 案例:异步操作MySQL 案例:FastAPl框架异步 案例:异步爬虫 课程总结
- python异步封装_python中用协程(异步)实现map函数,爬虫也可以封装进去,
1.python中得函数map(),通过加延时发现,是单线程执行,有阻塞,实现如下: import time def A(a): time.sleep(0.5) c = a + 11 return c ...
- python异步编程案例之超时
asyncio.wait_for(aw,timeout,*,loop=None) timeout可以是None也可以是一个float或int类型的数字,表示需要等待的秒数.如果timeout是None ...
- python 异步编程——asyncio
python 异步编程--asyncio 摘要 1. 协程 1.1 基本概念 1.2 实现方法 1.2.1 greenlet 1.2.2 yield 1.2.3 asyncio模块 1.2.4 asy ...
- python3异步编程_协程 Python异步编程(asyncio)
协程(Coroutine) 也可以被称为微线程,是一种用户态内的上下文切换技术.简而言之,其实就是通过一个线程实现代码块相互切换执行. 直接上代码,例如: 同步编程 import time def f ...
- python异步编程视频_asyncio异步编程【含视频教程】
Python Python开发 Python语言 asyncio异步编程[含视频教程] 不知道你是否发现,身边聊异步的人越来越多了,比如:FastAPI.Tornado.Sanic.Django 3. ...
- Python异步编程实战入门:从概念到实战
概述 读者可前往我的博客获得更好的阅读体验 在Python中存在GIL机制,该机制保证了在Python中同时间内仅能运行一行代码,这导致了Python无法真正实现多线程,但可以通过多进程打破GIL限制 ...
最新文章
- AS:西湖郑钜圣/鞠峰-人类肠道中特定耐药基因累积可能导致糖尿病风险上升
- 读写锁的由奢入俭“易”
- 写微博picgp图床安装与问题解决(看这一篇就可以了)
- Fedora 17 install VMWare tool
- hdu 4864 Task(贪婪啊)
- IE浏览器兼容性处理与提示
- 高精度加法(简明版C语言),高精度加法(简明版C语言)
- SQL PASS西雅图之行——会议篇
- nginx限制ip访问(转)
- Linux的版本可分为,Linux不同分类标准下的各种版本解读
- 通信工程专业高级工程师职称申报经验分享
- Access update语句 提示 操作必须使用一个可更新的查询
- FPGA产生m序列及其应用
- armbian 斐讯n1_斐讯N1刷入Armbian(linux)或者电视盒子系统
- python-random模块详解
- 广域网的应用场景是什么?
- c语言求100以内被7整除的最大自然数,编程,求100以内被7整除的最大自然数
- PAT练习 蜜蜂寻路
- 产品有复杂的卡扣倒扣,我们如何设计模具结构?
- java怎么语音转换成文字_Annyang将语音转换为文本