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
這個網站解決了大家開始設計階段的問題,輕量級的各種設計模型,強烈推薦。