【发布时间】:2020-10-30 01:11:08
【问题描述】:
在 lua 中工作,我有一个键/值对表
local fmtsToRun = {
name = function()
return configSubTable
end
}
长度可以是 1 个或多个条目。我需要遍历每个条目并运行一个子进程(通过一些 libuv C 绑定)。
对于正常的 for 循环,子进程会在循环完成运行后返回 libuv,导致出现乱序。结果是
- 循环开始
- 循环条目 1
- 工作 1 开始
- 循环条目 2
- 工作 2 开始
- 循环结束
- Job1 返回
- Job2 返回
我需要的是
- 循环开始
- 循环条目 1
- 工作 1 开始
- Job1 返回
- 循环条目 2
- 工作 2 开始
- Job2 返回
- 循环结束
我也尝试编写自己的pairs() 版本并使用协程之类的东西来处理回调
for fmt, output in jobIterator(fmtsToRun) do
print('finished running', output)
end
local function jobIterator(tbl)
return coroutine.wrap(function()
local fmtConf, fmtName
fmtName, fmtConf = next(tbl, fmtName)
if nil~=fmtConf then
local conf = fmtConf()
local output = nil
-- wrapper util from Libuv library
local job = Job:new({
cmd = conf.cmd,
args = conf.args,
on_stdout = onStdout, -- process output
on_stderr = onStderr, -- process any error
on_exit = function()
coroutine.yield(fmtName, output)
end
})
job.send(conf.data)
end
end)
end
这会导致此错误消息。
attempt to yield across C-call boundary
在保持正确顺序的同时等待job 完成并继续循环的“正确”方式是什么?
【问题讨论】:
-
我只使用 os.execute() 而不是协程。这样,您就可以保证在开始新任务之前,当前流程将按所需顺序完成。