協程其實就是可以由程式自主控制的執行緒
在python裡主要由yield 和yield from 控制,可以通過生成者消費者例子來理解協程
利用yield from 向生成器(協程)傳送資料# 傳統的生產者-消費者是乙個執行緒寫訊息,乙個執行緒取訊息,通過鎖機制控制佇列和等待,但一不小心就可能死鎖。
# 如果改用協程,生產者生產訊息後,直接通過yield跳轉到消費者開始執行,待消費者執行完畢後,換回生產者繼續生產,效率極高
def consumer():r = ''
while true:
n = yield r
if not n:
return
print('[consumer] consuming %s...' % n)
r = '200 ok'
def produce(c):
c.send(none)
n = 0
while n < 5:
n = n + 1
print('[producer] producing %s...' % n)
r = c.send(n)
print('[producer] consumer return: %s' % r)
c.close()
c = consumer()
produce(c)
# 注意到consumer函式是乙個generator,把乙個consumer傳入produce後:理解上面的例子對python的協程理解很重要# 首先呼叫c.send(none)啟動生成器;
# 然後,一旦生產了東西,通過c.send(n)切換到consumer執行;
# consumer通過yield拿到訊息,處理,又通過yield把結果傳回;
# produce拿到consumer處理的結果,繼續生產下一條訊息;
# produce決定不生產了,通過c.close()關閉consumer,整個過程結束。
# 整個流程無鎖,由乙個執行緒執行,produce和consumer協作完成任務,所以稱為「協程」,而非執行緒的搶占式多工。
# 最後套用donald knuth的一句話總結協程的特點:
# 「子程式就是協程的一種特例。」
下面是python3.4支援協程的寫法
import threadingimport asyncio
@asyncio.coroutine
def hello(s):
print(s)
print('hello world! (%s)' % threading.currentthread())
yield from asyncio.sleep(1)
print(s)
print('hello again! (%s)' % threading.currentthread())
loop = asyncio.get_event_loop()
tasks = [hello('w'), hello('e')]
loop.run_until_complete(hello('o'))
# 新增到task 表示一起執行
loop.run_until_complete(asyncio.wait(tasks))
tasks2 = [hello('w'), hello('e'),hello('h')]
print('++++++++++++++++++++')
loop.run_until_complete(asyncio.wait(tasks2))
loop.close()
# 由乙個執行緒通過coroutine併發完成。# async和await是針對coroutine的新語法,要使用新的語法,只需要做兩步簡單的替換:
# 把@asyncio.coroutine替換為async;
# 把yield from替換為await。
# 注意新語法只能用在python 3.5以及後續版本,如果使用3.4版本,則仍需使用上一節的方案。
import asyncioasync def hello():
print("hello world!")
r = await asyncio.sleep(1)
print("hello again!")
loop=asyncio.get_event_loop()
loop.run_until_complete(hello())
關於協程 nodejs和golang協程的不同
nodejs和golang都是支援協程的,從表現上來看,nodejs對於協程的支援在於async await,golang對協程的支援在於goroutine。關於協程的話題,簡單來說,可以看作是非搶占式的輕量級執行緒。一句話概括,上面提到了 可以看作是非搶占式的輕量級執行緒 在多執行緒中,把一段 放...
關於協程的 send None
這段時間太忙了,沒時間更新部落格。今天把python撿起來,看了下 協程。記錄乙個一開始沒太明白的點。直接貼 def consumer r j 0 while true n yield r 3 j j 1 print j d j if not n return print consumer cons...
Unity關閉協程,無法立刻殺死協程的問題
使用stopcoroutine 名字 或stopcoroutine 方法名 無法立刻殺死協程,還是會執行到結尾。stopcoroutine 用string引數,只可以關閉startcoroutine 方法使用相同string引數開啟的攜程。需要建立協程變數,並在startcorutine 開啟協程時...