Skip to content
Go back

Lua to-be-close 协程锁

Edit page

最近有个想法,想使用Lua5.4的特性to-be-close来实现协程锁。 moon中版本的实现是要单独把同步的流程放到一个函数中,然后排队,这样就有一个缺点:不能有返回值。 所以想用to-be-close配和协程挂起来实现,代码也非常简单。

queue.lua

local status = coroutine.status
local running = coroutine.running
local yield = coroutine.yield
local resume = coroutine.resume

local make_queue = make_queue
local queue_push = queue_push
local queue_pop = queue_pop

local M = {}

M.__index = M

function M.new()
    local obj = {}
    obj.queue = make_queue()
    return setmetatable(obj,M)
end

function M.scope_lock(self)
	if self.thread and status(self.thread) ~= "dead" then
		queue_push(self.queue, (running()))
		yield()
	end
	self.thread = running()
	return setmetatable({}, { __close = function()
		local co = queue_pop(self.queue)
		if co then
			resume(co)
		end
	end})
end

return M

使用示例


local moon = require("moon")
local queue = require("queue")

local mutex = queue.new()

moon.async(function()
	local lock<close> = mutex.scope_lock(mutex)
	moon.sleep(10000)
	print("run step 1")
end)

moon.async(function()
	local lock<close> = mutex.scope_lock(mutex)
	moon.sleep(5000)
	assert(false)
	print("run step 2")
end)

moon.async(function()
	local lock<close> = mutex.scope_lock(mutex)
	moon.sleep(1000)
	print("run step 3")
end)

moon.async(function()
	local lock<close> = mutex.scope_lock(mutex)
	moon.sleep(500)
	print("run step 4")
end)

会按调用流程执行,输出

run step 1
run step 2
run step 3
run step 4

Edit page

Previous Post
Asio 读取性能优化
Next Post
Asio HTTP-HTTPS 代理实现