今天遇到一个问题,在大厅服务中,如果一个请求使用到了一个公共的变量,如何保证其一致性?
虽然请求是挨个运行的,但是skynet.call会阻塞。
“同一个 skynet 服务中的一条消息处理中,如果调用了一个阻塞 API ,那么它会被挂起。挂起过程中,这个服务可以响应其它消息。这很可能造成时序问题,要非常小心处理。”
在其他语言中,比如c#,我们使用lock的办法,把变量或者执行的代码锁起来。
在skynet中用下面的办法解决
local sk_queue = require "skynet.queue"
local cs = sk_queue()
把要执行的代码写到cs里面
cs(func1)
这样就行了。
类似的需要小心的还有 ipairs pairs的遍历。
遍历pairs的时候非常小心别变动pairs(t)里面的t的结构。
否则会发生一些莫名其妙的事情。有时间做做实验。
ipairs (t)
返回三个值(迭代函数、表 t 以及 0 ), 如此,以下代码
for i,v in ipairs(t) do body end
将迭代键值对(1,t[1]) ,(2,t[2]), ... ,直到第一个空值。
pairs (t)
如果 t 有元方法 __pairs, 以 t 为参数调用它,并返回其返回的前三个值。
否则,返回三个值:next 函数, 表 t,以及 nil。 因此以下代码
for k,v in pairs(t) do body end
能迭代表 t 中的所有键值对。
参见函数 next 中关于迭代过程中修改表的风险。