1.在python3.4之前,協程是通過生成器(yield)實現的:
def count_down(n):
while n > 0:
yield n
n -= 1
if __name__ ==
'__main__'
: rest = count_down(5)
print(next(rest))
print(next(rest))
print(next(rest))
print(next(rest))
print(next(rest))
控制台輸出:
543
21
或者將yield當成是乙個賦值語句,實現協程的函式
def test_yield(
): while true:
n =(yield)
print(n)
if __name__ ==
'__main__'
: rest = test_yield(
) next(rest)
rest.send(
'666'
) rest.send(
'666'
)
控制台輸出:
666
666
2.python3.4之後,使用async和await關鍵字實現
使用async定義特殊的函式,當被呼叫時,不執行裡面的**,而是返回乙個協程物件,在事件迴圈中呼叫執行**前,協程物件不執行任何操作,因此,要先定義乙個事件迴圈佇列,並註冊任務,即新增進事件佇列,然後等待佇列前面的任務執行結束,呼叫該任務,執行
當遇到阻塞呼叫的函式時,用await函式將協程的控制權讓出,佇列先呼叫其他的任務
import asyncio
async def do_sth(x):
print(
'等待中:'.format(x))
await asyncio.sleep(x)
print(asyncio.iscoroutinefunction(do_sth))
coroutine = do_sth(5)
# 事件迴圈佇列
loop = asyncio.get_event_loop(
)# 註冊任務
task = loop.create_task(coroutine)
print(task)
#執行直到結束
loop.run_until_complete(task)
print(task)
控制台輸出:
true # 是協程函式
) running at d:/untitled/test_xiecheng/test.py:4>>
等待中:5
) done, defined at d:/untitled/test_xiecheng/test.py:4> result=none>
3.協程通訊之巢狀呼叫:
乙個協程的執行過程,依賴於另乙個協程函式的返回
import asyncio
async def comput(x, y):
print(
'正在計算x+y==>+'.format(x,y))
await asyncio.sleep(2)
# asyncio的sleep返回的是乙個協程物件
return x+y
async def get_sum(x,y):
rest = await comput(x,y)
# rest = comput(x,y)
# 假設comput是乙個相對任務(用asyncio模組中的sleep來模擬),
# 等待comput函式執行結束之後要得到結果。用上await即可
print(
'+='.format(x, y, rest))
loop = asyncio.get_event_loop(
)loop.run_until_complete(get_sum(1, 2))
loop.close(
)
4.協程通訊之佇列
import asyncio
import random
async def add(q,name):
for i in range(10):
await asyncio.sleep(random.randint(1,3))
await q.put(i)
print(
'add:,q.size:'.format(name,q.qsize()))
async def reduce(q,name):
while true:
await asyncio.sleep(random.randint(1, 5))
await q.get(
) print(
'reduce:,q.size:'.format(name,q.qsize()))
q = asyncio.queue(maxsize=5)
a1 = add(q,'a1'
)r = reduce(q,'r'
)# 事件迴圈佇列
loop = asyncio.get_event_loop(
)# 註冊任務
#執行直到結束
loop.run_until_complete(asyncio.gather(a1,r))
loop.close(
)
控制台部分輸出:
add:a1,q.size:1
add:a1,q.size:2
reduce:r,q.size:1
add:a1,q.size:2
reduce:r,q.size:1
此時由於get相關**等待的時間比put長一些,所以會存在add多個,才有乙個get的操作 Python 程序 執行緒 協程
程序和執行緒之間的關係 執行緒是屬於程序的,執行緒執行在程序空間內,同一程序所產生的執行緒共享同一記憶體空間,當程序退出時該程序所產生的執行緒都會被強制退出並清除。執行緒可與屬於同一程序的其它執行緒共享程序所擁有的全部資源,但是其本身基本上不擁有系統資源,只擁有一點在執行中必不可少的資訊 如程式計數...
Python 程序,執行緒, 協程
程序是系統進行資源分配和排程的乙個獨立單位 最小單位 程序的幾個狀態 空 新建 建立執行乙個程式的新程序,可能的事件有 新的批處理作業 互動登入 終端使用者登入到系統 作業系統因為提供一項服務而建立 由現有的程序派生等。新建 就緒 作業系統準備好再接納乙個程序時,把乙個程序從新建態轉換為就緒態。就緒...
執行緒丶程序丶協程(三)協程
協程,又稱微執行緒,纖程。英文名coroutine。協程是python個中另外一種實現多工的方式,只不過比執行緒更小占用更小執行單元 理解為需要的資源 為啥說它是乙個執行單元,因為它自帶cpu上下文。這樣只要在合適的時機,我們可以把乙個協程 切換到另乙個協程。只要這個過程中儲存或恢復 cpu上下文那...