關於協程的問題總結

2021-08-27 03:07:41 字數 2258 閱讀 4547

協程其實就是可以由程式自主控制的執行緒

在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後:

# 首先呼叫c.send(none)啟動生成器;

# 然後,一旦生產了東西,通過c.send(n)切換到consumer執行;

# consumer通過yield拿到訊息,處理,又通過yield把結果傳回;

# produce拿到consumer處理的結果,繼續生產下一條訊息;

# produce決定不生產了,通過c.close()關閉consumer,整個過程結束。

# 整個流程無鎖,由乙個執行緒執行,produce和consumer協作完成任務,所以稱為「協程」,而非執行緒的搶占式多工。

# 最後套用donald knuth的一句話總結協程的特點:

# 「子程式就是協程的一種特例。」

理解上面的例子對python的協程理解很重要

下面是python3.4支援協程的寫法

import threading

import 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 asyncio

async 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 開啟協程時...