對lua協程的一點理解

2022-03-06 08:04:52 字數 2612 閱讀 4062

讀《programming in lua》協程那一章,比較困惑的還是procuer-consumer那個例子:

function

consumer(prod)

while

true

dolocal x =receive(prod)

print

(x)

endend

function

receive(prod)

local status, value = coroutine.resume

(prod)

return

value

endfunction

send(x)

coroutine.yield(x) --

go back to where resumed

endfunction

producer()

return

coroutine.create(function

()

while

true

dolocal x = io.read

() send(x)

endend

)end

--consumer-driven design

consumer(producer())

producer產生資料,consumer消費資料,producer與consumer都在各自的協程中完成, **很短,但是很難讀 - 至少不是那麼一目了然,尤其比起這個直接的迴圈:

function

produce()

return

io.read

()end

function

consume(x)

print

(x)end

while

true

dolocal x =produce()

consume(x)

end

好在**?

書中說可以新增快取控制速度,或者進行資料過濾 - 但是這在迴圈版本的producer-consumer中也都能做到,無非在在實現produce是多些邏輯,或者再加個filter的函式處理produce的返回值,協程版本毫無優勢可言。

實在要說其優點,恐怕只是:producer和consumer的**在各自的協程中實現,並通過resume-yield交換資料 - 實現了松耦合。這是個優點,可以還是不太滿意,再往下看時,看到了全排列那個例子,稍作修改,讓我比較直觀的感覺到了協程這種控制結構的靈活性:

function

send(a)

coroutine.yield

(a)end

function

receive(prod)

local status, value = coroutine.resume

(prod)

return

value

endfunction

consumer(prod)

local

function

print_result(a)

for _, v in

ipairs(a) do

io.write(v, "")

endio.write('\n'

)

endwhile

true

dolocal a =receive(prod)

ifnot a then

break

endprint_result(a)

endend

function

producer(a)

function

permgen(a, n)

if n == 0

then

send(a)

--send something for consuming from an recursive call

else

for i=1, n do

a[n], a[i] =a[i], a[n]

permgen(a, n-1

) a[n], a[i] =a[i], a[n]

endend

endlocal n =table.getn(a)

return

coroutine.create(function() permgen(a, n) end

)end

consumer(producer())

這裡全排列採用了遞迴演算法:對陣列中的每個元素,把它交換到陣列末尾,然後對前n-1個元素的子陣列做同樣的事,當n==0時,輸出乙個排列。

這個在produce的時候,因為在乙個遞迴呼叫中,你無法乙個個返回:

於是,協程的有點就顯現出來了,不同於簡單函式中的return,協程可以在找到乙個排列後,yield掛起本協程並返回該排列,返回到原來resume這個協程的**處,取得資料進行consume,然後繼續resume進入協程獲取排列 - 通過協程靈活控制流程並傳遞資料,十分漂亮。

所以,那個迴圈版本的問題是:並不是所有produce的資料,都可以簡單的return回來的。

對協程的理解

對於作業系統來說,協程其實是一種特殊的執行緒,對於cpu來說,協程是非搶占式 程序和執行緒是搶占式的 實現機理如下 有兩個function a,b,a呼叫b,b要執行一段時間,很晚才返回,a不會因為等b而一直占用cpu,即a是非阻塞的。b返回後,a又能繼續執行。神奇的是,a和b又是走在一條獨木橋 橋...

對協程的理解

實現併發,可以使用多程序,多執行緒。程序和執行緒有個共同點,他們都是通過作業系統來排程的。而協程,則把排程的權力交給了程式設計師。協程可以看作使用者態下協作的執行緒。使用者態 是說協程的排程權屬於程式設計師。協作 是說協程的排程是協作式的,不是搶占的。在協程中,某部分可以通過呼叫某個方法,將控制權交...

Lua的協程基礎

參考 lua中的協同程式 coroutine 協同程式 coroutine 三個狀態 suspended 掛起,協同剛建立完成時或者yield之後 running 執行 dead 函式走完後的狀態,這時候不能再重新resume coroutine.create arg 根據乙個函式建立乙個協同程式,...