(轉)Lampard--【Lua基礎系列】協程

【Lua基礎系列】協程

大家好,我是Lampard~~

歡迎來到Lua進階系列的博客

前文再續,書接上一回。今天和大家講解一下lua中的協程

 

(一) 什麼是協程
Lua 協同程序(coroutine)與線程(這裏的線程指的是操作系統的線程)比較類似:擁有獨立的堆棧,獨立的局部變量,獨立的指令指針,同時又與其它協同程序共享全局變量和其它大部分東西。

一個多線程程序可以同時運行幾個線程(併發執行、搶佔),而協程卻需要彼此協作地運行,並非真正的多線程,即一個多協程程序在同一時間只能運行一個協程,並且正在執行的協程只會在其顯式地要求掛起(suspend)時,它的執行纔會暫停(無搶佔、無併發)。

協同程序有點類似同步的多線程,在等待同一個線程鎖的幾個線程有點類似協同程序。

協程的用法:

 

 

coroutine.running就可以看出來,coroutine在底層實現就是一個線程,當create一個coroutine的時候就是在新線程中註冊了一個事件。

 

(二) resume和yeild

resume和yeildr的協作是Lua協程的核心

 

 

舉一個經典生產者消費者例子:創建一個生產工廠,讓它生產20件產品,每生產一件就把協程掛起,等待客戶下一次提交需求的時候才重新resume喚醒

local newProductor
 
function productor()
    local i = 0
    while true do
        i = i + 1
        send(i)     -- 將生產的物品發送給消費者
    end
end
 
function consumer()
    local i = receive()
    while i < 20 do
        print(i)
        i = receive()
    end
end
 
function receive()
    -- 喚醒程序
    local status, value = coroutine.resume(newProductor)
    return value
end
 
function send(x)
    coroutine.yield(x)     -- x表示需要發送的值,值返回以後,就掛起該協同程序
end
 
-- 創建生產工廠
newProductor = coroutine.create(productor)
consumer()

 

測試結果:

 

 

(三) 協程的作用:

我作爲客戶端,參與項目一年多,其實一直都是單線程開發的,對於多線程,協程這些爲何存在一直不太理解,知道查閱了這篇博客稍微的瞭解一些:協程的好處是什麼?

一開始大家想要同一時間執行那麼三五個程序,大家能一塊跑一跑。特別是UI什麼的,別一上計算量比較大的玩意就跟死機一樣。於是就有了併發,從程序員的角度可以看成是多個獨立
的邏輯流。內部可以是多cpu並行,也可以是單cpu時間分片,能快速的切換邏輯流,看起來像是大家一塊跑的就行。 但是一塊跑就有問題了。我計算到一半,剛把多次方程解到最後一步,你突然插進來,我的中間狀態咋辦,我用來儲存的內存被你覆蓋了咋辦?所以跑在一個cpu裏面的併發都需要處理
上下文切換的問題。進程就是這樣抽象出來個一個概念,搭配虛擬內存、進程表之類的東西,用來管理獨立的程序運行、切換。 後來一電腦上有了好幾個cpu,好咧,大家都別閒着,一人跑一進程。就是所謂的並行。 因爲程序的使用涉及大量的計算機資源配置,把這活隨意的交給用戶程序,非常容易讓整個系統分分鐘被搞跪。所以核心的操作需要陷入內核(kernel),切換到操作系統,讓老大幫你
來做。 有的時候碰着I
/O訪問,阻塞了後面所有的計算。空着也是空着,老大就直接把CPU切換到其他進程,讓人家先用着。當然除了I\O阻塞,還有時鐘阻塞等等。一開始大家都這樣弄,後
來發現不成,太慢了。爲啥呀,一切換進程得反覆進入內核,置換掉一大堆狀態。進程數一高,大部分系統資源就被進程切換給喫掉了。後來搞出線程的概念,大致意思就是,這個地方
阻塞了,但我還有其他地方的邏輯流可以計算,這些邏輯流是共享一個地址空間的,不用特別麻煩的切換頁表、刷新TLB,只要把寄存器刷新一遍就行,能比切換進程開銷少點。

 

比如在進程裏面寫一個邏輯流調度的東西,碰着i\o我就用非阻塞式的(比如在加載資源時,我們可以做一些初始化場景的邏輯)。那麼我們即可以利用到併發優勢,又可以避免反覆系統調用,還有進程切換造成的開銷,分分鐘給你上幾千個邏輯流不費力。這就是協程。

 

原文地址:https://blog.csdn.net/cooclc/article/details/112640610

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章