Lua在子流程之后返回输出



在lua工作,我有一个键/值对表

local fmtsToRun = { 
name = function() 
return configSubTable
end
}

长度可以是1个或多个条目。我需要循环遍历每个条目并运行一个子进程(通过一些libuvC绑定(。

对于正常的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完成并继续循环?

一个更好的选择是手动控制流,并递归调用一个函数,一次遍历一个表项。

local runner = {}
for _, output in pairs(fmtsToRun) do
table.insert(runner, output)
end
jobIterator(runner)
local function jobIterator(tbl)
local F = {}
function F.step()
if #tbl == 0 then
return
end
local current = table.remove(tbl, 1)
F.run(current)
end

function F.run(conf)
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()
-- do what you need with output
print(output)
F.step()
end
}
)
job.send(conf.data)
end
F.step()
end

最新更新