自学内容网 自学内容网

同步库如何转化为异步,使用协程

将同步库转化为异步操作的基本思路是使用协程来模拟异步行为。对于同步库,通常我们可以使用以下几种方法来将其转化为异步操作:

  1. 使用 concurrent.futures:

    • concurrent.futures 提供了 ThreadPoolExecutorProcessPoolExecutor,可以用来在后台线程或进程中运行同步函数,并通过协程来等待其结果。
  2. 使用 asynciorun_in_executor:

    • asyncio 提供了 run_in_executor 方法,可以在异步函数中调用同步函数,并使其在后台线程或进程中运行。

下面是一个将同步库转化为异步操作的示例:

示例:将同步 HTTP 请求库 requests 转化为异步操作

同步代码(使用 requests:

import requests

def fetch_url(url: str):
    response = requests.get(url)
    return response.text

def main():
    urls = ["http://example.com", "http://example.org"]
    for url in urls:
        content = fetch_url(url)
        print(content)

if __name__ == "__main__":
    main()

异步代码(使用 requestsasyncio:

import asyncio
import concurrent.futures
import requests

def fetch_url(url: str):
    response = requests.get(url)
    return response.text

async def fetch_url_async(url: str, loop):
    # 使用 run_in_executor 来运行同步函数
    return await loop.run_in_executor(None, fetch_url, url)

async def main():
    urls = ["http://example.com", "http://example.org"]
    loop = asyncio.get_event_loop()
    
    tasks = [fetch_url_async(url, loop) for url in urls]
    contents = await asyncio.gather(*tasks)

    for content in contents:
        print(content)

if __name__ == "__main__":
    asyncio.run(main())

解释

  1. fetch_url: 同步函数,使用 requests 库获取 URL 内容。
  2. fetch_url_async: 异步函数,通过 loop.run_in_executor 在后台线程中运行同步函数 fetch_url,并将其结果返回给协程。
  3. main: 创建异步任务,并通过 asyncio.gather 同时运行这些任务。

使用 aiohttp 替代 requests

为了更好地利用异步特性,可以使用 aiohttp 来替代 requestsaiohttp 本身就是异步的,可以直接用于异步请求:

import aiohttp
import asyncio

async def fetch_url(url: str):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    urls = ["http://example.com", "http://example.org"]
    tasks = [fetch_url(url) for url in urls]
    contents = await asyncio.gather(*tasks)

    for content in contents:
        print(content)

if __name__ == "__main__":
    asyncio.run(main())

总结

  • 将同步库转化为异步:使用 concurrent.futuresasyncio.run_in_executor 可以在异步代码中运行同步函数,但这种方式不会完全发挥异步的优势。
  • 使用原生异步库:如果可能,使用原生异步库(如 aiohttp)是更优的选择,因为它们本身设计为异步操作,能更好地处理并发和 I/O 操作。

原文地址:https://blog.csdn.net/qq_39698985/article/details/140583981

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!