lua简单的互斥为线程应用程序

时间:2015-03-06 12:01:54

标签: multithreading lua locking mutex

我正在为某些应用编写扩展程序/插件。

在其文档中,它说插件有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()的作用。
- 如果原始表在被迭代时被修改,这个循环是否会返回至少旧状态?
- 在这种情况下,某些kv是否可能不会被迭代?

其他问题是我写的应用程序真的是黑盒子,我甚至不确定它将在哪个操作系统上运行(Win,Mac,Linux)。登记/> 我知道的所有内容都是100%,我有线程和socket模块。


您能否查看提供的代码?
它会起作用吗?

互斥锁是否还有其他可能性 可能会socket给出一些东西吗?

1 个答案:

答案 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
}