2016 - 2024

感恩一路有你

使用Python 3.7进行异步编程的入门例子

浏览量:4343 时间:2024-06-29 21:42:10 作者:采采

Python是一种非常流行的编程语言,它提供了许多强大的功能和库,使得编写高效的程序变得更加容易。其中一个非常有用的功能是异步编程,这在处理I/O密集型任务时非常有用。在本经验中,我们将介绍如何使用Python 3.7进行异步编程,并提供一个简单的入门示例。

1. 使用async/await实现异步编程

首先,我们来看一个使用async/await语法实现的异步程序示例。所有的异步函数声明都要加上async关键字。在一个async函数内,异步调用需要使用await或者其它方式“异步等待”。要运行一个async函数,需要使用来执行。下面是一个例子:

```

import asyncio

async def my_task(task_id):

print(f"Starting task {task_id}")

await (2)

print(f"Finished task {task_id}")

async def main():

await (

my_task(1),

my_task(2),

my_task(3)

)

if __name__ "__main__":

(main())

```

上述代码会输出以下结果:

```

Starting task 1

Starting task 2

Starting task 3

Finished task 1

Finished task 2

Finished task 3

```

2. 使用串行方式实现相同的程序

为了说明异步编程的优势,我们可以使用传统的阻塞式代替异步版本,来实现与上述async/await版本完全等价的串行程序。下面是一个例子:

```

import time

def my_task(task_id):

print(f"Starting task {task_id}")

(2)

print(f"Finished task {task_id}")

def main():

for i in range(1, 4):

my_task(i)

if __name__ "__main__":

main()

```

上述代码会输出以下结果:

```

Starting task 1

Finished task 1

Starting task 2

Finished task 2

Starting task 3

Finished task 3

```

3. 对执行代码进行计时

如果我们对异步版本和串行版本的执行时间进行比较,就能够更好地理解异步编程的好处。下面是一个在代码中插入计时函数的例子,可以发现三个my_task都执行完毕总共花了2*36秒。

4. 使用create_task和gather改进异步程序

但是,如果使用三个await按照顺序等待,会浪费时间。第一个my_task陷入sleep开始等待时,完全可以启动第二个my_task。所以,我们可以使用_task依次创建3个my_task,并用收集它们。下面是一个例子:

```

import asyncio

async def my_task(task_id):

print(f"Starting task {task_id}")

await (2)

print(f"Finished task {task_id}")

async def main():

tasks []

for i in range(1, 4):

task _task(my_task(i))

(task)

await (*tasks)

if __name__ "__main__":

(main())

```

上述代码会输出以下结果:

```

Starting task 1

Starting task 2

Starting task 3

Finished task 1

Finished task 2

Finished task 3

```

5. 异步调用的工作原理

需要注意的是,async/await机制并不是多线程或多进程等方式,而是单线程实现的。async/await用于描述控制流何时切换。一个异步调用必须将其awaited。当async函数进入等待时,调用async函数的一方会保存现场,并层层传导,层层暂停返回。我们可以想象成一棵运行树,从造成等待的叶子节点(I/O等待,网络等待,定时等待..)逐层返回并冻结执行现场,然后接着运行其它任务。虽然只有一个线程,但是它在多个async任务之间按照设定好的方式interleaving,提升了CPU的繁忙程度和多任务处理。

6. 注意事项

最后需要注意的是,如果我们没有await一个async调用,会有警告提示。这表示该调用不会暂停当前执行现场,并在其它地方执行代码。因此,我们应该始终await异步调用,以确保程序正确运行。

版权声明:本文内容由互联网用户自发贡献,本站不承担相关法律责任.如有侵权/违法内容,本站将立刻删除。