异步协程

协程,线程和进程的区别

  • 多线程:多进程通常利用的是多核 CPU 的优势,同时执行多个计算任务。每个进程有自己独立的内存管理,所以不同进程之间要进行数据通信比较麻烦。

  • 多线程:多线程是在一个 cpu 上创建多个子任务,当某一个子任务休息的时候其他任务接着执行。多线程的控制是由 python 自己控制的。 子线程之间的内存是共享的,并不需要额外的数据通信机制。但是线程存在数据同步问题,所以要有锁机制。

  • 多协程:协程的实现是在一个线程内实现的,相当于流水线作业。协程是一个线程中执行,没有线程切换的开销,所以对于并发编程,可以优先使用协程。

asyncio

在Python的asyncio库中,asyncawait是用于异步编程的关键字,引入了异步/协程(coroutine)的概念

异步编程是一种处理并发任务的方式,使得程序能够在等待某些I/O操作(如文件读写、网络请求等)的同时继续执行其他任务,而不会发生阻塞。作用:

  • 提高程序效率:异步编程可以充分利用I/O等待时间,使得程序在等待操作完成时能够继续执行其他任务,从而提高了整体程序的效率。

  • 改善用户体验:在网络编程中,异步操作可以避免阻塞用户界面,使得应用程序更加流畅。

  • 简化并发编程:通过使用async和await关键字,可以更方便地编写并发程序,避免了传统多线程编程中的锁和同步问题。

用法:

  1. 定义异步函数,使用async关键字

  2. 在异步函数中,使用await 关键字执行可等待对象(Coroutine、Task、Future),等待子函数执行完成,再往下执行。(在并发操作中,把程序控制权教给主程序,让他分配其他协程执行。) await 只能在带有 async 关键字的函数中运行。

  3. 通过 asyncio.create_task() / asyncio.gather() 创建任务

  4. asyncio.run 运行任务

# 定义异步函数
async def fetch_data(index):
   print(f"Fetching data {index}...")
   await asyncio.sleep(2)  # 模拟网络请求
   print(f"Data {index} fetched.")
   return f"Data {index}"

async def main():
   tasks = [fetch_data(i) for i in range(2)]
   results = await asyncio.gather(*tasks)
   print("All data fetched:", results)

# 执行任务
asyncio.run(main())
  • asyncio.create_task() 用于创建一个协程任务,接受一个协程对象作为参数,并返回一个任务对象,该任务对象可以用来控制和管理该协程的执行,包括取消、等待其执行完成等

  • asyncio.gather() 用于同时运行多个协程,并等待全部完成。接受一系列的协程对象(或者 Future 对象)作为参数,并返回一个协程对象,该协程对象会在所有给定的协程都执行完毕后完成

  • asyncio.run 函数运行协程程序,协程函数作为参数传入

在一个async函数内部,通过await可以调用另一个async函数,这个调用看起来是串行执行的,但实际上是由asyncio内部的消息循环控制;

在一个async函数内部,通过await asyncio.gather()可以并发执行若干个async函数。

posted @ 2024-10-14 19:56  hjy1995  阅读(7)  评论(0编辑  收藏  举报