用Lua模拟并行性

我正在尝试使用Lua来原型化一些并行算法。我指的是用纯Lua编写代码,在其中执行测试、调试等操作。当我有信心它可以运行时,我可以将其转换为真正的多线程库,甚至转换为另一种语言(如OpenCL内核)。显然,我不关心原型代码的性能。

我想使用一个在每行中都yield的协程,并加入一些样板代码来随机选择下一个“线程”运行。例如:

local function parallel_simulation(...)

  local function_list = {...}
  local coroutine_list = {}
  local thread_number = #function_list
  for i = 1, thread_number do
    coroutine_list[i] = coroutine.create(function_list[i])
  end

  while 0 < thread_number do

    local current = math.random(1, thread_number)
    local worker = coroutine_list[current]

    coroutine.resume(worker)

    if 'dead' == coroutine.status(worker) then
      thread_number = thread_number - 1
      table.remove(coroutine_list, current)
    end
  end
end

----------------------------------------------------------
-- Usage example

local Y = coroutine.yield
local max = 3
local counter = 0
local retry = 99

local function increment()
  Y() local c = counter
  Y() while max > c do
  Y()   c = counter
  Y()   c = c + 1
  Y()   counter = c
  Y() end
end

for i=1,retry do
  counter = 0
  parallel_simulation(increment, increment)
  if max ~= counter then
    print('Test SUCCESS ! A non-thread-safe algorithm was identified .', i, counter)
    return
  end
end

error('Test FAIL ! The non-thread-safe algorithm was not identified .')

这只是一个想法,任何涉及纯Lua的解决方案都受欢迎!这个解决方案让我非常不舒服,原因是所有的Y()。有没有什么方法可以避免它们?(debug.sethook不允许yield...)

第一次编辑-提供了更有意义的示例

编辑2-希望我清楚地表述了我想要实现的内容

点赞
用户3377142
用户3377142

一个将 Y() 放在每一行前面的简单替代方法是使用 gsubload

Y = coroutine.yield
max = 3
counter = 0

code = [[
function increment()
  local c = counter
  while max > c do
    c = counter
    c = c + 1
    counter = c
  end
end]]
code = code:gsub("\n  ", "\n  Y() ") -- 将 find/replace 中的两个空格替换为您使用的任何 Tab 字符。
assert(load(code))()

local retry = 99
-- 其余代码在此处

(根据您的 Lua 版本使用 loadloadstring) 请注意,变量声明 Y/max/counter 必须为全局变量,否则加载的函数将无法访问它们。类似地,code 中的函数必须是全局的,否则 increment 将不存在于加载的代码之外。

当然,这样的解决方案假设每行上的所有指令都是原子/线程安全的。

我建议对 parallel_simulation 进行改进,以添加一些改变下一个线程选择方式的方法,例如,也许仅当一个线程在执行初期而另一个线程即将完成时才会显示错误 - 虽然通过充分的随机试验可以达到这种状态,但添加一个允许您调整哪些线程更有可能被选择的参数(例如使用权重)应该可以使它更加可能发生。

2017-09-08 06:33:43