skynet的併發處理

skynet是一個異步響應的單進程多協程系統。
在skynet的服務中,如果調用了一個阻塞API(skynet.call skynet.sleep),這個服務將會被掛起。在阻塞返回之前,這個服務仍然 可以響應其他消息。這個就會造成時序問題了。
以下爲例

local CMD = {}
function CMD.func1()
    print('------func1 1')
    print('------func1 2')
end
function CMD.func2()
    print('------func2 1')
    skynet.sleep(2000)
    print('------func2 2')
end

以上的代碼中,若func2先調用,然後進入了sleep中,此時func1也會響應調用。
所以最後看到的輸出有可能是這個樣子的

------func2 1
------func1 1
------func1 2
------func2 2

還有可能是

func2 1 func2 1
func2 2 func2 2

爲了避免第2 種情況的發生,需要對它進行加鎖

local queue = require "skynet.queue"
local cs = queue()

function CMD.func2()
    cs(function()
        print('------func2 1')
        skynet.sleep(2000)
        print('------func2 2')
    end)
end

這樣加鎖以後,無論如何也不會出現第2種情況,它的輸出只會是

func2 1 func2 2 
func2 1 func2 2 
func2 1 func2 2

雖然skynet是個單線程的系統,但是它是異步響應的,所以對於時序問題也要加倍小心。

原文鏈接在這裏
https://github.com/cloudwu/skynet/wiki/CriticalSection

https://www.processon.com/i/568c6ea4e4b0e51d149a085f
這個網站解決了大家開始設計階段的問題,輕量級的各種設計模型,強烈推薦。

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