使用Python 3.7進行異步編程的入門例子
Python是一種非常流行的編程語言,它提供了許多強大的功能和庫,使得編寫高效的程序變得更加容易。其中一個非常有用的功能是異步編程,這在處理I/O密集型任務時非常有用。在本經驗中,我們將介紹如何使用P
Python是一種非常流行的編程語言,它提供了許多強大的功能和庫,使得編寫高效的程序變得更加容易。其中一個非常有用的功能是異步編程,這在處理I/O密集型任務時非常有用。在本經驗中,我們將介紹如何使用Python 3.7進行異步編程,并提供一個簡單的入門示例。
1. 使用async/await實現(xiàn)異步編程
首先,我們來看一個使用async/await語法實現(xiàn)的異步程序示例。所有的異步函數(shù)聲明都要加上async關鍵字。在一個async函數(shù)內,異步調用需要使用await或者其它方式“異步等待”。要運行一個async函數(shù),需要使用來執(zhí)行。下面是一個例子:
```
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. 使用串行方式實現(xiàn)相同的程序
為了說明異步編程的優(yōu)勢,我們可以使用傳統(tǒng)的阻塞式代替異步版本,來實現(xiàn)與上述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. 對執(zhí)行代碼進行計時
如果我們對異步版本和串行版本的執(zhí)行時間進行比較,就能夠更好地理解異步編程的好處。下面是一個在代碼中插入計時函數(shù)的例子,可以發(fā)現(xiàn)三個my_task都執(zhí)行完畢總共花了2*36秒。
4. 使用create_task和gather改進異步程序
但是,如果使用三個await按照順序等待,會浪費時間。第一個my_task陷入sleep開始等待時,完全可以啟動第二個my_task。所以,我們可以使用_task依次創(chuàng)建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機制并不是多線程或多進程等方式,而是單線程實現(xiàn)的。async/await用于描述控制流何時切換。一個異步調用必須將其awaited。當async函數(shù)進入等待時,調用async函數(shù)的一方會保存現(xiàn)場,并層層傳導,層層暫停返回。我們可以想象成一棵運行樹,從造成等待的葉子節(jié)點(I/O等待,網絡等待,定時等待..)逐層返回并凍結執(zhí)行現(xiàn)場,然后接著運行其它任務。雖然只有一個線程,但是它在多個async任務之間按照設定好的方式interleaving,提升了CPU的繁忙程度和多任務處理。
6. 注意事項
最后需要注意的是,如果我們沒有await一個async調用,會有警告提示。這表示該調用不會暫停當前執(zhí)行現(xiàn)場,并在其它地方執(zhí)行代碼。因此,我們應該始終await異步調用,以確保程序正確運行。