python异步编程案例之协程执行和停止

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

执行协程
asyncio提供了三种执行协程的机制

  1. 使用asyncio.run()执行协程(仅限于python3.7以上版本)。此函数总是创建一个新的事件循环,并在最后关闭它。建议将它用作asyncio程序的主入口,如main(),并且只调用一次。在同一个线程中,当已经有asyncio事件循环在执行时,不能调用此函数。
  2. await一个协程。在一个已经运行协程中await另一协程。
import asyncio


async 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
  1. 定义一个事件循环对象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 time

async 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仍是active
    return "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异步编程:使用`create_task`并发执行协程 阅读详情

相关推荐

26、Python异步编程协程:效率提升的关键技术

本文介绍了Python异步编程协程的概念,重点阐述了它们在提升程序执行效率方面的关键作用。文章通过生动的生活实例,解释了异步编程协程的原理,并展示了如何在网络编程、数据库操作等场景中应用这些技术。同时,文章还提供了实用的技巧案例,如使用`asyncio`库、异步上下文管理器`async with`语句等,以帮助读者更好地理解应用异步编程协程。通过学习这些技术,开发者可以有效地提高Python程序的执行效率,应对现代软件开发中的性能优化挑战。

silenceallat的博客 1059

Python协程的四种实现方式

Python协程的四种实现方式

weixin_45005677的博客 3387

一文掌握python协程asyncio(一)

一文掌握python协程asyncio

qq_38120851的博客 1549

python中强制关闭线程、协程、进程方法

python使用中多线程、多进程、多协程使用是比较常见的。那么如果在多线程等的使用,我们这个时候我们想从外部强制杀掉该线程请问如何操作?下面我就分享一下我的执行看法:

良知犹存的博客 1万+

优雅的退出asyncio事件循环

import asyncio import functools import os import signal """ 信号值 符号 行为 2 SIGINT 进程终端,CTRL+C 9 SIGKILL 强制终端 15 SIGTEM 请求中断 20 ...

dianyin7770的博客 1765

python3-asyncio 学习笔记 3 -- run_until_complete

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34128534的博客 8639

python 异步编程协程

python 协程原理使用

qq_43745578的博客 1732

深入理解同步与异步编程协程管理在Python中的应用

是一个非常实用的函数,它允许同时启动多个协程,并等待所有协程执行完成。这样的错误处理机制确保了即使在异步任务失败时,程序也能继续运行,从而提高了整体的容错性。进行并发编程时,不仅需要管理多个协程的并发执行,同时也需要妥善处理可能出现的错误取消正在运行的任务。中,取消任务是异步编程中的另一个重要方面,它允许开发者在任务不再需要时终止执行,从而释放资源。进行耗时的I/O操作,比如网络请求或文件读取,程序将在此函数执行期间停止执行,直到操作完成。函数中,等待任务完成,并处理可能由任务取消引发的异常。

lph159的博客 2546

python异步编程(基于asyncio)

异步编程允许程序在等待某些操作(如I/O操作、网络请求或定时器)完成时不阻塞(即不停止)主线程的执行,从而提高程序的效率响应速度。在异步编程中,程序可以启动一个长时间运行的任务,然后继续执行其他任务,而无需等待该任务完成事件循环,可以把他当做是一个while循环,这个while循环在周期性的运行并执行一些任务,在特定条件下终止循环。其实也可以理解为就是创建一个死循环,比如while循环;

m0_56059292的博客 1万+

解锁 Python 异步编程的强大潜力!—— 让你的代码飞速运行!

Python 中,最知名的异步编程库是 asyncio。这个库通过实现事件循环(Event Loop)、协程(Coroutines)非阻塞 I/O(Non-blocking I/O)来管理程序的执行。如果你希望构建高响应性高可扩展性的应用程序,强烈建议你深入研究这个库。

Xianxiancq的博客 7921

Python异步编程 - asyncio

Python异步编程 - asyncio

孤寒者的博客 1万+

Python 彻底解读协程与异步【看完包会】

title: Python 协程与异步 copyright: true top: 0 date: 2018-08-11 10:15:50 tags: categories: Python进阶笔记 permalink: password: keywords: 协程 description: Python2.7中用代码实现协程,同时区分同步与异步,以及异步的表现形式,回调与协程。 像烟花也是过一生,...

浪子燕青的博客 4222

python并发运行协程 asyncio.gather asyncio.wait

同步有序,异步无序 技巧: 几乎所有的异步框架都将异步编程模型简化:一次只允许处理一个事件。故而有关异步的讨论几乎都集中在了单线程内。 如果某事件处理程序需要长时间执行,所有其他部分都会被阻塞。 所以,一旦采取异步编程,每个异步调用必须“足够小”,不能耗时太久。如何拆分异步任务成了难题。 0.协程理解: 一份详细的asyncio入门教程 [进阶]-Python3 异步编程详解(史上最全篇) F...

weixin_44818729的博客 1万+

python异步编程案例之FutureTask

Task是跟事件循环交互的一种主要方式。创建Task意思就是把coroutine封装成Task实例,并追踪 coroutine 的完成状态。Task 是 Future 的子类,因此这个Task实例可以作为变量传给其他代码。也就是说其他代码可以直接await这个Task,并且不需要知道原始的coroutine是如何被创建的, 并且在 Task 完成时还可以获取coroutine 的返回值。 两种创建...

HighDS的博客 2609

PythonPython异步编程

异步编程是一种编程范式,通过非阻塞的方式执行任务,允许程序在等待某些操作(如I/O操作、网络请求、数据库查询等)完成时,继续执行其他任务。这与同步编程(或阻塞编程)形成对比,后者在等待操作完成时会阻塞执行流程,直到任务完成才继续执行。asyncawait说明:异步并不简单的等于并发,更精准的表述应该是并发,也即多个任务在同一时间段内交替运行,而不是同时运行。

Python、Golang、大数据 2622

asyncawait到底怎么用?Python异步编程入门全解析

掌握Python异步编程从这里开始!本文深入讲解Python 3.5 async/await 语法入门,解析协程原理、适用场景与核心用法,提升IO密集型任务效率。对比传统同步代码,助你写出更高效的网络爬虫与Web服务,值得收藏。

CompiShoal的博客 961

python异步编程案例之事件循环

先定义一个协程函数 import asyncio async def do_some_work(x): print("Hello:",x) return "work is done for {}".format(x) 要让这个do_some_work(2)协程对象运行的话,有两种方式: 在另一个已经运行的协程中用 await 等待它 通过 ensure_future 函数计划...

HighDS的博客 1132

Python中async协程快速理解

当你在一个函数定义前加上async def时,你就创建了一个协程函数。协程函数被调用时,它不会立即执行里面的代码,而是返回一个协程对象。这个协程对象是一个可等待 (awaitable) 的对象。print("开始执行协程")await asyncio.sleep(1) # 模拟耗时操作print("协程执行完毕")

m0_60388871的博客 2140
上一篇: python异步编程案例之事件循环
下一篇: python异步编程案例之协程并发
HighDS
博客等级 码龄7年 13粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值