首页  >  文章  >  后端开发  >  什么时候应该使用 Python 3.5 的 asyncio 的 `await` 功能,什么时候应该避免使用它?

什么时候应该使用 Python 3.5 的 asyncio 的 `await` 功能,什么时候应该避免使用它?

Barbara Streisand
Barbara Streisand原创
2024-11-17 04:41:03815浏览

When should you use Python 3.5's `await` feature for asyncio, and when should you avoid it?

何时使用和避免 Python 3.5 的 Asyncio 等待功能

Python 3.5 引入了await 关键字以方便使用 asyncio 进行异步编程。然而,并不总是清楚应该等待哪些操作来最大化效率。

确定异步候选者

经验法则是等待任何执行 I/ 的函数O 操作,如访问网络或读取文件。这些操作可能会长时间阻塞同步代码。通过等待它们,asyncio 可以同时执行其他操作。

异步代码的优点

如下面的代码片段所示,异步代码可以显着加快涉及以下操作的操作:多个 I/O 调用:

# Synchronous way:
download(url1)  # takes 5 sec.
download(url2)  # takes 5 sec.
# Total time: 10 sec.

# Asynchronous way:
await asyncio.gather(
    async_download(url1),  # takes 5 sec. 
    async_download(url2)   # takes 5 sec.
)
# Total time: only 5 sec. (+ little overhead for using asyncio)

具有混合异步/同步代码的函数

异步函数可以调用异步和同步函数。但是,等待不执行 I/O 操作的同步代码没有任何优势。这可能会带来不必要的开销:

async def extract_links(url):  

    # async_download() was created async to get benefit of I/O
    html = await async_download(url)  

    # parse() doesn't work with I/O, there's no sense to make it async
    links = parse(html)  

    return links

避免长时间运行的同步操作

避免异步内长时间运行的同步操作(> 50 ms)至关重要函数,因为它们可以冻结所有其他异步任务。要高效处理这些任务:

  • 使用多重处理: 在单独的进程中执行长时间运行的操作并等待结果:
executor = ProcessPoolExecutor(2)

async def extract_links(url):
    data = await download(url)
    links = parse(data)
    # Now your main process can handle another async functions while separate process running    
    links_found = await loop.run_in_executor(executor, search_in_very_big_file, links)
  • 使用 ThreadPoolExecutor: 对于 I/O 密集型同步任务,例如对 Web 服务器的请求:
executor = ThreadPoolExecutor(2)

async def download(url):
    response = await loop.run_in_executor(executor, requests.get, url)
    return response.text

以上是什么时候应该使用 Python 3.5 的 asyncio 的 `await` 功能,什么时候应该避免使用它?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn