上下文管理器(同步&异步)

异步上下文管理器(async with)和同步上下文管理器(with)的区别主要在于它们的工作方式与事件循环的配合。理解这一点可以帮助你更好地使用它们处理 I/O 操作,尤其是在异步编程中。以下是两者的主要区别:

工作方式#

  • 同步上下文管理器 (with)

    • 同步上下文管理器用于同步代码块,它会在进入 with 块时执行 __enter__ 方法,并在退出 with 块时执行 __exit__ 方法。
    • with 块中,所有操作是同步的,程序会按顺序执行,不会立即返回,直到 with 块中的代码执行完毕。
    • 示例:文件操作、数据库连接、线程锁等常见同步操作。
    with open('example.txt', 'r') as file:
        content = file.read()
    # 这里的代码是同步的,程序会等待文件操作完成才继续执行
    
  • 异步上下文管理器 (async with)

    • 异步上下文管理器用于异步编程,它同样具有 __enter____exit__ 方法,但是它们是异步的(使用 async def 定义),并且需要使用 await 来等待其完成。
    • 这意味着它适用于 I/O 密集型的操作,比如网络请求、数据库查询或文件操作等,它们可以并发执行,而不会阻塞事件循环。
    • 使用 async with 时,进入和退出上下文时的操作是异步执行的,因此它允许在等待 I/O 操作完成时执行其他任务。
    import aiofiles
    
    async with aiofiles.open('example.txt', 'r') as file:
        content = await file.read()
    # 这里的代码是异步的,程序会在等待文件操作时执行其他任务
    

应用场景#

  • 同步上下文管理器 (with)

    • 适用于执行一些需要阻塞等待的操作,比如读取文件、访问数据库或进行一些需要锁定资源的操作(如多线程中的锁)。
    • 在同步编程中,with 是非常常见的。
  • 异步上下文管理器 (async with)

    • 主要用于 I/O 密集型的操作,特别是当操作会导致等待(如网络请求、文件系统操作、数据库查询等)时。
    • 使用 async with 可以避免在等待 I/O 操作时阻塞主线程,从而提高程序的效率和响应性。
    • 例如,在 aiohttp(异步 HTTP 请求)或 aiofiles(异步文件操作)中,我们通常会使用 async with

如何实现#

  • 同步上下文管理器

    • 通过实现 __enter____exit__ 方法来定义上下文管理器的行为。

    示例:

    class MyContextManager:
        def __enter__(self):
            print("Enter")
            return self
        
        def __exit__(self, exc_type, exc_val, exc_tb):
            print("Exit")
            
    with MyContextManager() as manager:
        print("Inside the context")
    # Output:
    # Enter
    # Inside the context
    # Exit
    
  • 异步上下文管理器

    • 通过实现 __aenter____aexit__ 方法来定义异步上下文管理器的行为。

    示例:

    class MyAsyncContextManager:
        async def __aenter__(self):
            print("Async Enter")
            return self
        
        async def __aexit__(self, exc_type, exc_val, exc_tb):
            print("Async Exit")
            
    import asyncio
    
    async def main():
        async with MyAsyncContextManager() as manager:
            print("Inside the async context")
            
    asyncio.run(main())
    # Output:
    # Async Enter
    # Inside the async context
    # Async Exit
    

性能差异#

  • 同步上下文管理器

    • 在执行 I/O 操作时,程序会被阻塞,直到操作完成。例如,如果在文件读取过程中等待,整个程序将停下来,直到文件内容被读取完。
  • 异步上下文管理器

    • 异步上下文管理器允许你在等待 I/O 操作的同时,执行其他任务。对于大量 I/O 密集型操作,这会显著提高程序的效率,因为它避免了阻塞操作。

常见使用库#

  • 同步上下文管理器open(文件操作)、threading.Lock(线程锁)、sqlite3.connect(数据库连接)等。
  • 异步上下文管理器aiohttp.ClientSession(异步 HTTP 请求)、aiofiles.open(异步文件操作)等。

总结#

  • 同步上下文管理器with)适用于同步的、阻塞的操作,它等待一个操作完成后才进行下一个操作。
  • 异步上下文管理器async with)适用于异步编程,可以在等待 I/O 操作时允许程序执行其他任务,从而提高效率。

简而言之,选择 with 还是 async with,取决于你是在处理同步操作还是异步操作。在 I/O 密集型的异步场景下,推荐使用异步上下文管理器来避免阻塞。

作者:cloud-2-jane

出处:https://www.cnblogs.com/cloud-2-jane/articles/18620663

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   一只大学生  阅读(10)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示