我正在为某些应用编写扩展程序/插件。
在其文档中,它说插件有2个线程:
- "主线程"所有业务逻辑必须生活的地方
- "回调线程"应用程序通过事件调用具有预定义名称的回调,这些回调不能做复杂的事情并尽快返回
文档不是很清楚,因此可能不是从一个线程而是从多个线程调用回调。
我写了虚拟互斥,就是这样:
Mutex = class {
_lock = function(self, owner)
assert(owner, 'owner must be set')
local ts = Timestamp.get()
local key = tostring(owner) .. ' ' .. tostring(ts)
self[key] = ts
for k, v in pairs(self) do
if k ~= key and v <= ts then
self[key] = nil
return false
end
end
return key
end,
lock = function(self, owner, wait)
local wait = wait or 0.01
local k
repeat
k = self:_lock(owner)
if k then return k else sleep(wait) end
until k
end,
unlock = function(self, key)
self[key] = nil
end
}
并使用它来制作线程安全队列,如下所示:
ThreadSafeQueue = class {
new = function(cls)
return getmetatable(cls).new(cls, {
mx_queue = Mutex:new(),
mx_push = Mutex:new(),
})
end,
pop = function(self)
local lock_queue = self.mx_queue:lock(self)
local val
if #self then
val = table.remove(self, 1)
else
val = nil
end
self.mx_queue:unlock(lock_queue)
return val
end,
push = function(self, val)
if val == nil then return end
-- don't `push()` from few threads at the same time
local lock_push = self.mx_push:lock(val)
-- don't `pop()` when `push()` and `push()` when `pop()`
local lock_queue = self.mx_queue:lock(self)
self[#self + 1] = val
self.mx_queue:unlock(lock_queue)
self.mx_push:unlock(lock_push)
end
}
class
这里是帮助器,它返回带有原型查找的对象和设置metatable的:new()
方法。
主要问题是因为我不确定pairs()
的作用。
- 如果原始表在被迭代时被修改,这个循环是否会返回至少旧状态?
- 在这种情况下,某些k
,v
是否可能不会被迭代?
其他问题是我写的应用程序真的是黑盒子,我甚至不确定它将在哪个操作系统上运行(Win,Mac,Linux)。登记/>
我知道的所有内容都是100%,我有线程和socket
模块。
您能否查看提供的代码?
它会起作用吗?
互斥锁是否还有其他可能性
可能会socket
给出一些东西吗?
答案 0 :(得分:1)
选项:
尝试创建套接字,如果成功,则互斥锁定,否则 - 等待它关闭
local Mutex = class {
identities = {},
new = function(cls, identity)
assert(not cls.identities[identity])
local inst = getmetatable(cls).new(cls, {
port = identity,
server = nil
})
cls.identities[identity] = inst
return inst
end,
lock = function(self, wait)
local wait = wait or 0.01
local server
local ts = Timestamp.get()
repeat
server = socket.bind("*", self.port)
if server then
self.server = server
return true
else
sleep(wait)
end
assert(Timestamp.get() - ts < 3, 'deadlock')
until server
end,
unlock = function(self)
self.server:close()
self.server = nil
end
}