在Python中實現非同步程式設計,只需要這幾步就夠了

大雄45發表於2020-11-08
導讀 非同步程式設計是並行程式設計的一種方式。單個工作單元獨立於主應用程式執行緒執行,並通知呼叫執行緒其完成、失敗情況或進度。

非同步程式設計是並行程式設計的一種方式。單個工作單元獨立於主應用程式執行緒執行,並通知呼叫執行緒其完成、失敗情況或進度。下面這張圖理解起來會更直觀一些:
在Python中實現非同步程式設計,只需要這幾步就夠了在Python中實現非同步程式設計,只需要這幾步就夠了
同步程式設計很普遍。如圖,請求1被髮出後等待響應1;一旦得到響應1就發出請求2,然後等待它的響應。在上面的程式碼中,向函式傳遞引數“a”後等待函式返回更改後的值,然後再次呼叫以更改數字,最後再次得到響應,這就是同步程式設計。

而對於非同步程式設計來說,請求1被髮出後,無需等響應1便可直接發出請求2。兩個請求完成後得到兩個響應。簡單地說就是請求1和請求2是並行處理的,不等前一個請求的響應便提出新的請求。

簡言之,只要開啟工作管理員(macOS中的活動監視器)就能看到多個應用程式同步執行;或者一個Python  在兩個不同的終端視窗中執行。專業術語叫做多程式(MultiProcessing),顧名思義,即不止一個程式在執行。

如何在Python中進行非同步程式設計?

一個同步程式設計的示例程式碼如下:

deffun(length,a):
b = a
for i inrange(length):
a+=1
print("value of a before: "+str(b)+" now it's "+str(a))
return a
defmain():
r1 =fun(50000000,0)
r2 =fun(100,12)
r3 =fun(100,41)
if __name__=="__main__":
main()

以上程式碼的輸出:
在Python中實現非同步程式設計,只需要這幾步就夠了在Python中實現非同步程式設計,只需要這幾步就夠了
在Python中實現非同步程式設計,只需要這幾步就夠了
這段程式碼傳遞了for迴圈的範圍。執行程式碼耗時長達13.843秒,因為r1的範圍是5000,所以耗時久。現在的問題是,必須先待r1任務完成,否則無法得到r2和r3。可能在得到r1之前就得到r2和r3嗎?答案是肯定的,這正是非同步程式設計的用武之地。

首先用pip指令安裝非同步包。

pip install asyncio

安裝後,看一下新程式碼。使用非同步包:

import asyncio
asyncdeffun(length,a):
b = a
for i inrange(length):
a+=1
if i %10000==0:
await asyncio.sleep(0.0001)
print("value of a before: "+str(b)+" now it's "+str(a))
return a
asyncdefmain():
#creating subroutines.
t1 = loop.create_task(fun(50000000,0))
t2 = loop.create_task(fun(100,12))
t3 = loop.create_task(fun(100,41))
await asyncio.wait([t1,t2,t3])
if __name__=="__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

首先觀察該程式碼的輸出,接下來討論該程式碼:

在Python中實現非同步程式設計,只需要這幾步就夠了

在Python中實現非同步程式設計,只需要這幾步就夠了在Python中實現非同步程式設計,只需要這幾步就夠了
輸出-1

在Python中實現非同步程式設計,只需要這幾步就夠了
在Python中實現非同步程式設計,只需要這幾步就夠了在Python中實現非同步程式設計,只需要這幾步就夠了
輸出-2

輸出-1中首先能得到t2和t3程式的結果,然後在輸出-2的截圖中得到了t1程式的結果,這是非同步程式設計的功勞。t1程式耗時最長,所以它的結果最後產生,且t1、t2和t3程式均並行執行。非同步程式設計的好處就在於不必等待任何程式的結果,便可獲得下一個程式的結果。

讓我們討論一下此程式碼。

首先,在if __name__=="__main__"中定義了asyncio.get_event_loop(),並將這個迴圈作為處理迴圈事件的非同步物件。然後建立一個main的例行程式,並設定條件:若main沒完成則繼續迴圈。每次非同步,都要進行loop.close()的程式設計,否則結果就會錯誤或異常。

然後將函式定義為asyncdeffunc_name,這樣直譯器就知道函式用了非同步的方法。在main()中定義了三個任務(也可稱為子例程),並使用了await函式,以便它等待三個程式結束(即使它沒有多大意義,也必須使用它)。

最後用了fun()函式。i %10000的if條件讓最大範圍的程式徐徐執行,最後得到了答案。仔細研究fun()函式並自己嘗試的話,其中的邏輯會顯得非常合理和直接。

在Python中實現非同步程式設計,你學會了嗎?

原文來自:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2732833/,如需轉載,請註明出處,否則將追究法律責任。

相關文章