第101天: Python asyncio

简介: 第101天: Python asyncio

异步IO之asyncio


异步IO:当发起一个 IO 操作时,并不需要等待它的结束,程序可以去做其他事情,当这个 IO 操作结束时,会发起一个通知。


在 Python 中可以使用 asyncio 模块异步编程,用于协程、网络爬虫、同步等。

asyncio 中的概念


event_loop 事件循环


事件循环是 asyncio 应用的核心,管理所有的事件。

  1. 创建新的事件循环


asyncio.new_event_loop()
  1. 获取当前线程中正在执行的事件循环


asyncio.get_running_loop()
  1. 并发运行任务


asyncio.gather()
  1. 向指定的事件添加一个任务


asyncio.run_coroutine_threadsafe()
  1. 返回没有执行的事件


asyncio.all_tasks()


Future 对象


一个 Future 代表一个异步运算的结果,线程不安全。


Task 对象


Task 对象的作用是在运行某个任务的同时可以并发的运行其他任务

Task 对象可以使用 asyncio.create_task() 函数创建,也可以使用 loop.create_task() 和 asyncio.ensure_future() 函数创建,不建议实例化 Task对象

  1. 取消 Task 对象


cancel()
  1. Task 任务是否被取消


cancelled()
  1. Task 对象是否完成


done()
  1. 返回结果


result()


  • Task 对象被完成,则返回结果
  • Task 对象被取消,则引发 CancelledError 异常
  • Task 对象的结果不可用,则引发 InvalidStateError 异常
  1. 添加回调,任务完成时触发


add_done_callback(task)
  1. 所有任务列表
asyncio.all_tasks()
  1. 返回当前任务

asyncio.current_task()

运行协程


import asyncio
async def do_work():    print("Hello....")    # 模拟阻塞1秒    await asyncio.sleep(1)    print("world...")
coroutine = do_work()print(coroutine)
# 创建一个事件event_looploop = asyncio.get_event_loop()
# 将协程加入到event_loop中,并运行loop.run_until_complete(coroutine)


示例结果


<coroutine object do_work at 0x1108c50c8>Hello....# 这里会暂停1秒world...


在 Python 中使用 async def 定义一个协程( coroutine ),它并不能直接运行,需要加入到事件循环( event_loop )中


运行 Task


import asyncio
async def do_work():    print("这是一个Task例子....")    # 模拟阻塞1秒    await asyncio.sleep(1)    return "Task任务完成"
# 创建一个事件event_looploop = asyncio.get_event_loop()
# 创建一个tasktask = loop.create_task(do_work())# 第一次打印taskprint(task)
# 将task加入到event_loop中loop.run_until_complete(task)# 再次打印taskprint(task)print(task.result())


示例结果


<Task pending coro=<do_work() running at /Users/imeng/Documents/Interview/Python/asyncio_test.py:5>>这是一个Task例子....<Task finished coro=<do_work() done, defined at /Users/imeng/Documents/Interview/Python/asyncio_test.py:5> result='Task任务完成'>Task任务完成


使用 EventLoop 对象的 create_task 函数创建一个 Task 对象,在第一次打印 Task 对象

时,状态为 pending,完成执行函数后的状态为 finished

Task 对象的 result() 函数可以获取 do_work() 函数的返回值


Task 任务回调


import asyncio
async def do_work():    print("这是一个Task例子....")    # 模拟阻塞1秒    await asyncio.sleep(1)    return "Task任务完成"
# 任务完成后的回调函数def callback(task):    # 打印参数    print(task)    # 打印返回的结果    print(task.result())
# 创建一个事件event_looploop = asyncio.get_event_loop()
# 创建一个tasktask = loop.create_task(do_work())task.add_done_callback(callback)
# 将task加入到event_loop中loop.run_until_complete(task)

示例结果


这是一个Task例子....<Task finished coro=<do_work() done, defined at /Users/imeng/Documents/Interview/Python/asyncio_test.py:5> result='Task任务完成'>Task任务完成


定义回调函数时必须有一个参数,参数和 Task 任务时同一个对象,使用 add_done_callback() 函数为 Task 任务添加一个完成后的回调函数


并发任务


import asyncioimport time
async def do_work(t):    print("暂停" + str(t) + "秒")    # 模拟阻塞1秒    await asyncio.sleep(t)    return "暂停了" + str(t) + "秒"
# 任务完成后的回调函数def callback(future):    # 打印返回的结果    print(future.result())
# 创建一个事件event_looploop = asyncio.get_event_loop()
tasks = []i = 0while i <= 4:    task = loop.create_task(do_work(i))    task.add_done_callback(callback)    tasks.append(task)    i += 1;
# 计时now = lambda :time.time()start = now()# 将task加入到event_loop中loop.run_until_complete(asyncio.wait(tasks))
end = now()print("总共用时间:",end-start)


示例结果:



暂停0秒暂停1秒暂停2秒暂停3秒暂停4秒暂停了0秒暂停了1秒暂停了2秒暂停了3秒暂停了4秒总共用时间: 4.003800868988037


使用 asyncio.wait() 函数将 Task 任务列表添加到 event_loop 中,也可以使用 asyncio.gather() 函数


在示例中可以看出多个协程总共用时4秒多,如果是同步任务将需要花费10秒多,asyncio 实现了程序的并发


同一个回调


import asyncioimport functools
async def do_work(t):    print("暂停" + str(t) + "秒")    await asyncio.sleep(t)    return "暂停了" + str(t) + "秒"
def callback(loop, gatheringFuture):    print(gatheringFuture)    print("多个Task任务完成后的回调")    loop.stop()
loop = asyncio.get_event_loop()
gather = asyncio.gather(do_work(1), do_work(3))gather.add_done_callback(functools.partial(callback, loop))
loop.run_forever()


示例结果


暂停1秒暂停3秒<_GatheringFuture finished result=['暂停了1秒', '暂停了3秒']>多个Task任务完成后的回调


loop.run_forever() 函数 和 loop.run_until_complete() 函数 并不相同,

run_until_complete() 函数在执行后事件循环被停止,run_forever() 函数在 Task 任务执行完成后事件循环并没有被终止,在回调函数 callback() 中使用 loop.stop() 函数将事件循环停止


总结


asyncio 在协程、网络爬虫等多种耗时操作时程序不再需要等待其他任务完成,节约大量的时间。


代码地址

示例代码:https://github.com/JustDoPython/python-100-day/tree/master/day-101


系列文章


第100天:UDP 编程

第99天:TCP 编程

第98天:图像库 PIL 实例—验证码去噪

第97天:图像库 PIL(二)

第96天:图像库 PIL(一)

第95天:StringIO & BytesIO
第94天:数据分析之 pandas 初步第93天:文件读写第92天:Python Matplotlib 进阶操作
第91天:Python matplotlib introduction从 0 学习 Python 0 - 90 大合集总结

目录
相关文章
|
1月前
|
搜索推荐 程序员 调度
精通Python异步编程:利用Asyncio与Aiohttp构建高效网络应用
【10月更文挑战第5天】随着互联网技术的快速发展,用户对于网络应用的响应速度和服务质量提出了越来越高的要求。为了构建能够处理高并发请求、提供快速响应时间的应用程序,开发者们需要掌握高效的编程技术和框架。在Python语言中,`asyncio` 和 `aiohttp` 是两个非常强大的库,它们可以帮助我们编写出既简洁又高效的异步网络应用。
117 1
|
6天前
|
Python
Python中的异步编程:使用asyncio和aiohttp实现高效网络请求
【10月更文挑战第34天】在Python的世界里,异步编程是提高效率的利器。本文将带你了解如何使用asyncio和aiohttp库来编写高效的网络请求代码。我们将通过一个简单的示例来展示如何利用这些工具来并发地处理多个网络请求,从而提高程序的整体性能。准备好让你的Python代码飞起来吧!
18 2
|
10天前
|
调度 开发者 Python
Python中的异步编程:理解asyncio库
在Python的世界里,异步编程是一种高效处理I/O密集型任务的方法。本文将深入探讨Python的asyncio库,它是实现异步编程的核心。我们将从asyncio的基本概念出发,逐步解析事件循环、协程、任务和期货的概念,并通过实例展示如何使用asyncio来编写异步代码。不同于传统的同步编程,异步编程能够让程序在等待I/O操作完成时释放资源去处理其他任务,从而提高程序的整体效率和响应速度。
|
7天前
|
数据库 Python
异步编程不再难!Python asyncio库实战,让你的代码流畅如丝!
在编程中,随着应用复杂度的提升,对并发和异步处理的需求日益增长。Python的asyncio库通过async和await关键字,简化了异步编程,使其变得流畅高效。本文将通过实战示例,介绍异步编程的基本概念、如何使用asyncio编写异步代码以及处理多个异步任务的方法,帮助你掌握异步编程技巧,提高代码性能。
20 4
|
7天前
|
API 数据处理 Python
探秘Python并发新世界:asyncio库,让你的代码并发更优雅!
在Python编程中,随着网络应用和数据处理需求的增长,并发编程变得愈发重要。asyncio库作为Python 3.4及以上版本的标准库,以其简洁的API和强大的异步编程能力,成为提升性能和优化资源利用的关键工具。本文介绍了asyncio的基本概念、异步函数的定义与使用、并发控制和资源管理等核心功能,通过具体示例展示了如何高效地编写并发代码。
16 2
|
17天前
|
调度 开发者 Python
异步编程在Python中的应用:Asyncio和Coroutines
异步编程在Python中的应用:Asyncio和Coroutines
16 1
|
20天前
|
关系型数据库 MySQL 数据处理
探索Python中的异步编程:从asyncio到异步数据库操作
在这个快节奏的技术世界里,效率和性能是关键。本文将带你深入Python的异步编程世界,从基础的asyncio库开始,逐步探索到异步数据库操作的高级应用。我们将一起揭开异步编程的神秘面纱,探索它如何帮助我们提升应用程序的性能和响应速度。
|
24天前
|
调度 Python
python知识点100篇系列(20)-python协程与异步编程asyncio
【10月更文挑战第8天】协程(Coroutine)是一种用户态内的上下文切换技术,通过单线程实现代码块间的切换执行。Python中实现协程的方法包括yield、asyncio模块及async/await关键字。其中,async/await结合asyncio模块可更便捷地编写和管理协程,支持异步IO操作,提高程序并发性能。协程函数、协程对象、Task对象等是其核心概念。
|
29天前
|
调度 开发者 Python
异步编程在Python中的应用:Asyncio和Coroutines
【10月更文挑战第12天】本文介绍了Python中的异步编程,重点讲解了`asyncio`模块和协程的概念、原理及使用方法。通过异步编程,程序可以在等待I/O操作时继续执行其他任务,提高整体效率。文章还提供了一个简单的HTTP服务器示例,展示了如何使用`asyncio`和协程编写高效的异步代码。
16 2
|
30天前
|
调度 开发者 Python
异步编程在Python中的应用:Asyncio和Coroutines
【10月更文挑战第10天】本文介绍了Python中异步编程的应用,重点讲解了`asyncio`模块和协程的概念、原理及使用方法。通过一个简单的HTTP服务器示例,展示了如何利用`asyncio`和协程实现高效的并发处理。
18 1