迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Python >

Python - 等待异步函数完成

作者:迹忆客 最近更新:2023/06/21 浏览次数:

本文介绍如何创建异步函数并使用await 关键字中断进程。 我们还将学习如何在 Python 中使用任务而不是线程。


使用 await 关键字并创建一个异步函数

异步编程不是多线程; 它不是多处理而是并发编程。

我们不会讨论并发编程的整个思想和整个编码模式,但我们会讨论基本原理以及如何在 Python 中实现这些原理。

现在让我们看一个简单的例子; 我们有一个正在调用的 Func_1、Func_2 和 Func_3。

Func_1()
Func_2()
Func_3()

如果这些函数被异步调用,这意味着我们将调用 Func_1(),然后调用 Func_2()

Func_1() 返回时,我们只调用 Func_2(),当 Func_2() 返回时,我们将调用 Func_3()

如果我们使用多线程或多处理,那将与异步编程不同。 因为在多线程中,在这种情况下我们将定义三个线程,并且我们将同时运行所有这些函数。

或者,大致同时,我们将尝试同时运行它们,或者至少创造同时执行的假象。

但是,我们想做的是,比方说,Func_1() 做一些有成效的事情,然后它从数据库、API 请求一些数据,或者它只是为了等待而休眠。

如果发生这种情况,我们不想浪费 CPU 时间并开始执行 Func_2(),即使该函数尚未返回。 所以我们只能同时运行一个任务; 我们没有进行任何多处理或多线程。

但是,如果 Func_1() 正在睡眠、等待或无效率,那么我们可以利用这段时间开始执行 Func_2() 甚至 Func_3()。 要在Python中进行异步编程,我们必须导入一个名为asyncio的库。

由于我们不会将整个程序定义为异步,因此特定功能将是异步的; 我们需要使用 async 关键字来指定异步函数。

如果我们只有这个 Main_Func(),整个程序将是异步的,但我们将在下一个示例中添加其他函数。 在这个函数中,我们将使用两个 print() 函数。

并且,在这之间,我们要睡觉,但我们不会用 time.sleep(); 来睡眠。 我们将使用 asyncio.sleep()

我们需要在调用 asyncio.sleep() 之前使用await关键字,这意味着我们将等待第二个打印语句完成。 在完成之前,我们不会做任何其他事情。

要运行 Main_Func() 函数,我们需要使用 asyncio.run() ,并且在 run() 函数内部我们将传递 Main_Func() 函数。 我们必须调用 Main_Func() 函数; 我们不仅仅将其称为多线程。

import asyncio

async def Main_Func():
    print('Before waiting')
    await asyncio.sleep(1)
    print('After waiting')

asyncio.run(Main_Func())

输出:

python 等待异步函数完成 - 输出1

我们来介绍另一个异步函数Func_2(); 我们将打印两条语句并休眠两秒钟。

Main_Func() 函数内部,我们没有休眠,而是使用 wait 关键字调用 Func_2() 函数,但这不是异步的。

import asyncio

async def Main_Func():
    print('Before waiting')
    await Func_2()
    print('After waiting')

async def Func_2():
    print('Func_2: Before waiting')
    await asyncio.sleep(2)
    print('Func_2: After waiting')

asyncio.run(Main_Func())

由于我们正在等待函数,这与异步调用它是一样的,它不会执行这个直到所有指令都按照我们定义的那样完成。

Before waiting
Func_2: Before waiting
Func_2: After waiting
After waiting

它不是异步的; 但是,如果我们想在调用 Main_Func() 函数时执行类似的操作,则控件应打印 Main_Func() 函数的第一个打印语句。

然后,调用 Func_2() 函数,从而打印该函数的第一条打印语句。

当此函数处于休眠状态时,它应该打印 Main_Func() 函数的第二条打印语句,一旦完成,它应该打印 Func_2() 函数的第二条打印语句。


使用 create_task() 创建任务来解决问题

为此,我们需要处理任务,因此在 Main_Func() 函数的开头,我们将在调用 asyncio.create_task() 时创建一个任务,并在任务内部传递 Func_2()。

这意味着一旦我们有一些空闲时间,我们就会调用该任务。

import asyncio

async def Main_Func():
    Task=asyncio.create_task(Func_2())
    print('Before waiting')
    print('After waiting')

async def Func_2():
    print('Func_2: Before waiting')
    await asyncio.sleep(2)
    print('Func_2: After waiting')

asyncio.run(Main_Func())

运行代码后,我们可以看到从 Main_Func() 函数中打印了两条打印语句,然后就完成了。 并且执行了第一个 print 语句,但是在打印第二个 print 语句之前终止了执行。

Before waiting
After waiting
Func_2: Before waiting

这是因为 Main_Func() 是main函数,控件没有等待 Func_2() 函数,也就是说一旦控件执行到 Main_Func() 函数的末尾,控件就停止执行。

控件不需要等待 Func_2() 函数的第二个打印语句完成,以便控件将跳过它。 要修复它,我们将在 Main_Func() 函数的末尾使用 await Task。

import asyncio

async def Main_Func():
    Task=asyncio.create_task(Func_2())
    print('Before waiting')
    print('After waiting')
    await Task

async def Func_2():
    print('Func_2: Before waiting')
    await asyncio.sleep(2)
    print('Func_2: After waiting')

asyncio.run(Main_Func())

现在我们可以看到它是按照定义打印的。

Before waiting
After waiting
Func_2: Before waiting
Func_2: After waiting

如果我们想看看它是如何异步工作的,我们可以在 print 语句之间使用 sleep() 函数来实现。

这意味着我们将执行 Main_Func() 的第一个打印语句,然后控件将休眠一秒钟,这意味着 main 函数现在有空闲时间。

现在,任务有时间执行,直到 Main_Func() 完全运行。 由于 Main_Func() 函数正在休眠,这意味着我们现在有可用的 CPU 时间来通过使用任务调用 Func_2() 函数来开始执行该函数。

但是,Func_2() 函数也会进入睡眠状态,这意味着在该函数内部控件会等待两秒钟,然后控件会转到 Main_Func() 函数来打印第二条打印语句。

然后它终止,这意味着控件不再对 Func_2() 函数的其余部分感兴趣。

async def Main_Func():
    Task=asyncio.create_task(Func_2())
    print('Before waiting')
    await asyncio.sleep(1)
    print('After waiting')

输出:

Before waiting
Func_2: Before waiting
After waiting

如果我们想对此感兴趣,我们必须在 Main_Func() 函数末尾使用await Task。

它是异步的; 如您所见,顺序是 Main_Func() 函数打印第一个打印语句,然后 Func_2() 首先打印,然后 Main_Func() 打印第二个,Func_2() 打印第二个。

因为当函数进入睡眠状态时,会使用空闲时间,这样就不会浪费 CPU 时间。

python 等待异步函数完成 - 输出2

上一篇:在 Python 中列出虚拟环境

下一篇:没有了

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

在 Python 中列出虚拟环境

发布时间:2023/06/21 浏览次数:149 分类:Python

在本文中,我们将讨论什么是 Python 中的虚拟环境以及列出它们的一些命令。虚拟环境是一个独立的环境,我们可以在其中安装库、包、脚本和Python解释器。

Python 中的 Urljoin 简介

发布时间:2023/06/21 浏览次数:178 分类:Python

本篇文章介绍了如何使用 Python 中的 urljoin() 模块形成 URL,并介绍了使用该模块时的行为。

Python 中并发方面的差异

发布时间:2023/06/21 浏览次数:68 分类:Python

本文将讨论如何在Python中实现并发以及其优点和缺点。线程和多线程 线程在Python中已经存在很长时间了。

Python 中从线程获取返回值

发布时间:2023/06/21 浏览次数:145 分类:Python

这篇文章首先讨论了线程的基础知识,并提供了一个在Python中启动线程的代码示例。然后,我们将讨论一个在线程中获取函数返回值的代码。

在 Python 中从文本创建 N-Grams

发布时间:2023/06/21 浏览次数:65 分类:Python

本文将讨论如何使用 Python 中的功能和库创建 n-gram。使用 for 循环在 Python 中从文本创建 n-gram 我们可以有效地创建一个 ngrams 函数,该函数接受文本和 n 值,并返回一个包含 n-gram 的列表。

用于 Python 的 Vim 自动完成

发布时间:2023/06/21 浏览次数:180 分类:Python

Vim(Vi Improved的缩写)是一款功能强大的文本编辑器,常被作为Python开发环境的首选。本文将探讨Vim及其用于Python的自动补全功能。

Python 数独求解器

发布时间:2023/06/21 浏览次数:188 分类:Python

本文介绍了我们如何使用 Python 来解决数独问题。 通过适应回溯算法,它可以作为一个准确的数独解算器。

Python Quine 介绍

发布时间:2023/06/21 浏览次数:167 分类:Python

一个Quine是一个产生其源代码作为输出的计算机程序。Quine很有趣,因为它们似乎违背了编程的目的,即根据输入生成输出。运行Python Quine

Python 复利计算器

发布时间:2023/06/21 浏览次数:172 分类:Python

Python是用于金融分析的优秀语言,其中之一是可以使用Python计算复利。复利是指利息不仅仅在本金(原始金额)上支付,还包括已累计的利息。本文将讨论Python复利函数。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便