Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Lua中模拟并行性_Lua_Parallel Processing_Prototype - Fatal编程技术网

在Lua中模拟并行性

在Lua中模拟并行性,lua,parallel-processing,prototype,Lua,Parallel Processing,Prototype,我正在尝试使用lua来创建一些并行算法的原型。我的意思是用纯Lua编写代码,对它执行测试,调试它,等等。然后,当我确信它可以工作时,我可以将它转换为真正的多线程库,甚至转换为另一种语言(例如OpenCL kenel)。显然,我并不关心原型代码的性能 我想使用一个在每行生成的协同程序,用一些样板随机选择下一个要运行的“线程”。例如: local function parallel_simulation(...) local function_list = {...} local coro

我正在尝试使用lua来创建一些并行算法的原型。我的意思是用纯Lua编写代码,对它执行测试,调试它,等等。然后,当我确信它可以工作时,我可以将它转换为真正的多线程库,甚至转换为另一种语言(例如OpenCL kenel)。显然,我并不关心原型代码的性能

我想使用一个在每行生成的协同程序,用一些样板随机选择下一个要运行的“线程”。例如:

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 .')
局部函数并行模拟(…)
局部函数_list={…}
本地协程_列表={}
本地线程_编号=#函数_列表
对于i=1,螺纹号为
协程\列表[i]=协程.创建(函数\列表[i])
结束
而0<线程数
本地电流=数学随机数(1,螺纹编号)
本地工作者=协同程序列表[当前]
合作程序。简历(工作人员)
如果'dead'==coroutine.status(worker),则
螺纹号=螺纹号-1
表.remove(协同程序列表,当前)
结束
结束
结束
----------------------------------------------------------
--用法示例
局部Y=协同程序
本地最大值=3
本地计数器=0
本地重试=99
局部函数增量()
Y()本地c=计数器
Y()而max>c do
Y()c=计数器
Y()c=c+1
Y()计数器=c
Y()结束
结束
对于i=1,请重试执行
计数器=0
并行模拟(增量、增量)
如果max~=计数器,则
打印('测试成功!已识别非线程安全算法',i,计数器)
返回
结束
结束
错误('测试失败!未识别非线程安全算法')
这只是一个想法,任何涉及纯Lua的解决方案都是受欢迎的!是什么让我对这个解决方案感到非常不舒服呢。有没有办法避免它们?(debug.sethook不允许屈服…)

编辑1-提供了更有意义的示例


编辑2-希望我清楚了我要完成的任务

在每行前面放置
Y()
的简单替代方法是使用
gsub
load

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() ") -- replace two spaces in find/replace with whatever tab character(s) you use
assert(load(code))()

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

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


我建议对parallel_simulation进行改进,添加一些方法来更改下一个线程的选择方式。例如,可能只有当其中一个线程在执行早期,而另一个线程几乎完成时,错误才会被揭示——尽管理论上可以通过足够的随机试验达到这种状态,并且有一个参数允许您调整下一个更可能选择的线程(例如使用权重)应该更容易实现。

我不明白为什么要在每行之后传递控制。在并行执行中,您不确切知道指令执行顺序,因此我希望我的代码以相同的方式运行。例如,我想模拟并发值写入来发现互斥的需要。显然,我只能将收益率放在关键行上,但关键点是,我可能不知道哪一个是关键代码。假设下一步应该是在每个VM指令代码(测试下的块)之后产生。我不明白为什么这是有用的,当你可以,简单地说,做一个
sleep
函数,它会等待很长时间,让另一个任务进入,直到它们睡眠,等等。如果“任务”是指另一个系统进程,这不是我想要的,我想要来自同一进程(独立的“解释器”进程)的竞争条件。如果您指的是“Lua函数/协同路由”,则Lua执行模型不是抢占式的,即,在活动模型调用coroutine.yield之前,不能执行其他协同路由。睡眠只会使程序停止一段给定的时间,而不可能执行其他协程(或部分协程)。我的意思是,为什么不制作一个多线程程序,在一个人睡眠这么长时间时切换任务呢。我看不到任何合法的理由来运行tash,中断一条线,运行另一条线,等等。这是低效的,坦率地说,没有那么有用。