Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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
C++ lua_newstate vs lua_newthread_C++_Multithreading_Lua - Fatal编程技术网

C++ lua_newstate vs lua_newthread

C++ lua_newstate vs lua_newthread,c++,multithreading,lua,C++,Multithreading,Lua,我正在尝试将lua实现到我现有的多线程应用程序中。我听说lua不是线程安全的,我一直在为不同的线程创建不同的lua\u状态 通过查找lua头文件,我找到了lua\u newthread。您将如何在一个准备就绪的线程化应用程序中实现这一点。您是否创建一个lua\U状态并创建单独的lua\U新线程,或者这会导致其他问题?lua\U新闻状态创建一个新的lua状态。不同的州是完全不同的 lua\u newthread创建附加到给定lua状态的新lua线程。Lua状态可以在Lua VM内有多个执行线程,但

我正在尝试将lua实现到我现有的多线程应用程序中。我听说lua不是线程安全的,我一直在为不同的线程创建不同的
lua\u状态


通过查找lua头文件,我找到了
lua\u newthread
。您将如何在一个准备就绪的线程化应用程序中实现这一点。您是否创建一个lua\U状态
并创建单独的lua\U新线程,或者这会导致其他问题?

lua\U新闻状态
创建一个新的lua状态。不同的州是完全不同的

lua\u newthread
创建附加到给定lua状态的新lua线程。Lua状态可以在Lua VM内有多个执行线程,但它们不是并发执行的;它们是协同程序,可以共享数据


不要将Lua线程与操作系统线程混淆。

请注意,Lua线程不是操作系统线程(尽管名称有误导性),只是Lua本身(而不是主机应用程序)中用于以异步方式执行代码的工具


因此,答案是:在应用程序中的每个线程中创建一个
lua\u状态
,如果需要在状态之间传递数据,则使用序列化库作为中间件。

到目前为止,答案并没有提供实现lua块并行执行的各种方法的概述,这是我关于“多线程”lua主题的2美分:

您基本上可以将lua状态/引擎分为两部分。首先是全局环境,它包括lua状态的所有全局变量等。第二个是执行堆栈,它随着函数调用函数和程序执行而扩展和收缩。据我所知,有三种方法可以实现多个lua流的并行执行:

  • 最简单的是协程(这似乎是lhf的答案所说的),它可以通过使用协程库在纯lua中实现。如果您熟悉协作式多任务处理,则每个执行流都需要定期将处理器(或“产量”)明确移交给其他处理器。协同路由共享单个环境和全局变量空间,但每个协同路由都有一个单独的执行堆栈。因此,通过这种方式,可以有效地使2+个lua执行流同时处于活动状态,当然,在给定的时刻只有一个lua执行流,因为只有一个OS线程在执行这项工作
  • 优点:使用纯lua很容易实现(无需更改C代码)

    缺点:必须到处打电话的不便使代码看起来很糟糕。此外,较长的任务需要分解成小块,如果您不十分小心,那么如果您在产出调用之间的协同路由中执行较长的工作,可能会导致线程延迟变差。如果您有对长时间运行的C函数的调用,那么就没有办法产生中间运行,所以您运气不好,所有其他lua都必须等待

  • 另一个极端(正如michaelmeyer所建议的)是有多个OS线程,每个线程有一个专用的lua状态(由lua_newstate()返回)。这允许真正先发制人的多任务处理,包括在C或纯lua代码中,将实时lua任务优先于其他长时间运行的任务。在这种情况下,每个OS线程都有自己的环境和全局变量空间,以及自己的执行堆栈。此功能也可以在不修改库存lua代码的情况下实现(除了创建OS线程并为每个线程调用lua_newstate()),并且单独的lua引擎/状态彼此之间没有直接交互,因此不需要同步/互斥来保护lua环境。但最困难的部分是跨不同线程共享数据,因为每个线程都有一个全新的全局变量空间。有许多聪明的方法可以做到这一点(例如lua通道),包括来回序列化数据,在C级用户数据对象上共享数据,并在C中显式同步,等等
  • 优点:易于实现的现货lua代码,并可以充分利用无限数量的CPU内核

    缺点:在线程/状态之间共享变量和数据需要多种智能策略中的一种,这种共享通常需要在每次从lua访问共享变量时使用显式lua代码,以及在序列化和同步时浪费或空闲的CPU周期。它还使用了更多的内存,这在嵌入式系统中可能变得非常重要:我所从事的一个项目只需要为每个OS线程提供大约100kB的堆栈空间,但每个新的lua环境在加载所有绑定库和全局上下文后会使用额外的1.5MB

  • 一个很好的折衷方法是使用lua_newthread()从现有状态生成一个新状态,这将为您提供一个新创建的执行堆栈,但将与以前的lua状态共享现有环境和全局变量空间。然后,您可以继续在不同的操作系统线程上使用新创建的状态,以更可预测的最坏情况延迟,允许先发制人的多线程和实时任务优先级。但是在这种情况下,你!必须在C中实现lua_lock()和lua_unlock()函数,以在共享lua环境中提供互斥保护。在后台,luavm不断地调用这些函数(默认情况下,这些函数被定义为不执行任何操作)来锁定和解锁环境,以防止其他操作系统线程损坏环境。这种方法的巨大优势在于,不同的线程可以针对相同的全局变量空间同时运行lua,并真正并行执行。当通过lua绑定调用C函数时,这是在解锁环境的情况下完成的,因此,只要在这些C函数中完成了大部分计算成本高昂的工作,您甚至可以使大量CPU内核饱和。这