spring cloud 配置阿里資料庫連線池 druid
阿新 • • 發佈:2022-03-31
一、協程
協程,又稱微執行緒,纖程,也稱為使用者級執行緒,在不開闢執行緒的基礎上完成多工,也就是在單執行緒的情況下完成多工,多個任務按照一定順序交替執行
1、單執行緒+非同步協程(遇到Io阻塞會自動切換,利用阻塞時間就去執行其他任務)
在幾個程序之間隨意切換單個任務
實現協程的方法;
greenlet 早前模組
yield關鍵字
asyncio裝飾器(Python3.4)
async & await關鍵字(Python3.5) (推薦)
2、非同步程式設計
1.事件迴圈
理解成一個死迴圈,去檢測並執行某些程式碼,就是無限迴圈的做任務列表中的任務,直到任務做完為止
2.生成事件迴圈:
去生成或者獲取一個事件
loop = asyncio.get_event_loop()
將任務放到任務列表
loop.run_until_complete(任務)
3、解釋
協程函式:定義函式時前面加一個async
async def func():
協程物件:執行協程函式()得到的協程物件
result = func()
#### 執行協程函式,建立協程物件,函式內部程式碼都不會執行
執行:
import asyncio
async def func():
print("1234")
result = func()
#協程物件交給事件迴圈來處理才會執行
loop = asyncio.get_event_loop()
loop.run_until_complete(result)
#在python3.7以後執行:就是把上面兩句話轉為下面一句話
asyncio.run(result)
4、await關鍵字
await後面要跟可等待物件(協程物件、future、task物件),即io等待
await asyncio.sleep(2) #後面跟一個io等待物件
await就是等待物件,直到這個物件得到值以後才開始執行
5、task物件
事件迴圈中可以新增多個任務,用於併發排程協程
建立task物件
task1 = asyncio.create_task(協程函式) #python3.7以後
task1 = asyncio.ensure_future(協程函式) #Python3.7以前
現在使用:
import asyncio
async def func1(): #async就可以定義協程
print(1)
await asyncio.sleep(2) #遇到Io耗時操作時,就會切換到tasks中的其他任務
return '返回值'
async def main():
print(3)
tasks = [
asyncio.create_task(func1(),name='n1'), #拿到返回值才會執行
asyncio.create_task(func1(),name='n2') #拿到返回值才會執行
]
print(2)
done,pending = await asyncio.wait(tasks,timeout=None)
#timeout=None表示最多等待多少時間,done是所有函式返回結果,是一個集合,而pending表示最大等待時間完了後,還未完成的任務
asyncio.run(main())
6、asyncio.future物件(一般不用)
task繼承future物件,task物件內部await結果的處理基於future物件來的
7、concurrent.future物件
使用執行緒池、程序池實現非同步操作時才用得到
import time
from concurrent.future import Future
from concurrent.future.thread import ThreadPoolExecutor
from concurrent.future.thread import ProcessPoolExecutor
def func(value):
time.sleep(2)
print(value)
return 123
#建立執行緒池
pool = ThreadPoolExecutor(max_workers=5)
#建立程序池
pool = ProcessPoolExecutor(max_workers=5)
for i in range(10):
fut = pool.submit(func,1)
print(fut)
二、yield版本
import time def work1(): while True: print("work1") yield time.sleep(0.5) def work2(): while True: print("work2") yield time.sleep(0.5) def main(): w1 = work1() w2 = work2() while True: #無限迴圈 next(w1) #開啟協程 next(w2) if __name__ == "__main__": main()
三、greenlet
python中的greenlet模組對其封裝,從而使得切換任務變的更加簡單
先安裝模組
pip3 install greenlet
程式碼例項
import time import greenlet # 任務1 def work1(): for i in range(3): print("work1") time.sleep(1) # 切換到協程2裡面執行對應的任務 g2.switch() # 任務2 def work2(): for i in range(3): print("work2") time.sleep(1) # 切換到第一個協程執行對應的任務 g1.switch() if __name__ == '__main__': # 建立協程指定對應的任務 g1 = greenlet.greenlet(work1) g2 = greenlet.greenlet(work2) # 切換到第一個協程執行對應的任務 g1.switch()
四、gevent
相較於greenlet,這個gevent可以自動切換
同上先安裝包
import gevent def work(n): for i in range(n): # 獲取當前協程 print(gevent.getcurrent(), i) #用來模擬一個耗時操作,注意不是time模組中的sleep gevent.sleep(1) g1 = gevent.spawn(work, 3) g2 = gevent.spawn(work, 3) g3 = gevent.spawn(work, 3) g1.join() g2.join() g3.join()