我正在尝试将lua实现到我现有的多线程应用程序中.我听说lua不是线程安全的我lua_State(s)
为不同的线程创建了不同的东西.
浏览我发现的lua头文件lua_newthread
.您将如何将其实现为一个全部就绪的线程应用程序.您是创建一个lua_State
并创建单独的lua_newthread(s)
还是会导致其他问题?
lua_newstate
创造了一个新的Lua状态.不同的国家是完全分开的.
lua_newthread
创建一个附加到给定Lua状态的新Lua线程.Lua状态可以在Lua VM中有多个执行线程,但它们不会同时执行; 它们是协同程序,可以共享数据..
不要将Lua线程与操作系统线程混淆.
注意,Lua线程不是操作系统线程(尽管有误导性名称),只有Lua本身(不在主机应用程序中)以异步方式执行代码.
所以答案是:lua_State
在应用程序中为每个线程创建一个,如果需要在状态之间传递数据,则使用序列化库作为中间件.
到目前为止的答案并没有真正提供实现 lua 块并行执行的各种方法的概述,所以这是我关于“多线程”lua 主题的 2 美分:
您基本上可以将 lua 状态/引擎分为两部分。首先是全局环境,其中包括lua状态的所有全局变量等。其次是执行堆栈,它会随着函数调用函数和程序执行而扩展和收缩。据我所知,实现多个lua流并行执行的方式有以下三种:
优点:使用纯 lua 实现简单(无需更改 C 代码)
缺点:不得不到处放置 yield 调用的不便使代码看起来很糟糕。此外,更长的任务需要分解成小块,如果你不小心,如果你在 yield 调用之间在协程中执行更长的工作块,可能会导致糟糕的线程延迟。如果您调用了长时间运行的 C 函数,则无法在运行中产生结果,因此您很不走运,所有其他 lua 都必须等待。
优点:在股票 lua 代码上易于实现,并且可以充分利用无限数量的 CPU 内核
缺点:在线程/状态之间共享变量和数据需要多种聪明的策略之一,这种共享通常需要每次从 lua 访问共享变量时显式的 lua 代码,以及序列化和同步上的一些浪费或空闲的 CPU 周期. 它还使用了更多的内存,这在嵌入式系统上可能变得非常重要:我从事的一个项目每个 OS 线程只需要大约 100kB 的堆栈空间,但每个新的 lua 环境使用额外的 1.5MB一旦它加载了所有绑定库和全局上下文。
优点:数据共享要简单得多,而且几乎没有 CPU 开销(尽管您仍然需要在读取时注意其他可能正在写入变量的线程,例如在另一个线程添加到表时迭代表。 )
缺点:在 lua 执行过程中大量调用互斥锁会产生少量开销(在我的情况下,这会导致大约 6% 的 CPU 开销 - 有点打击,但值得付出代价)。此外,如果您试图在多个内核之间传播大量纯 lua 工作,由于对 lua 环境的共享访问,您最终会遇到瓶颈 - 尽管根据我的经验,您通常不会花费大部分时间CPU 周期运行纯 lua。您通常将大部分 CPU 周期花费在由 lua 调用的 C 函数中,在此期间您不拥有对环境的锁定,这不会阻止代码在其他内核上运行。