实际上我正在使用visual C ++来尝试将lua函数绑定为套接字事件的回调(在另一个线程中)。我在一个线程中初始化lua的东西,而套接字在另一个线程中,所以每次套接字发送/接收消息时,它都会调用lua函数,而lua函数根据内部的'tag'确定它应该做什么。消息。
所以我的问题是:
由于我将相同的Lua状态传递给lua函数,这样安全吗?它不需要某种保护吗? lua函数是从另一个thead调用的,所以我猜他们可能会被同时调用。
如果不安全,这种情况的解决方案是什么?
答案 0 :(得分:2)
异步回调到Lua状态是不安全的。
有很多方法可以解决这个问题。最受欢迎的是某种民意调查。
最近的通用同步库是DarkSideSync
与libev绑定的流行Lua是lua-ev
This SO answer推荐Lua Lanes和LuaSocket。
答案 1 :(得分:1)
在多个线程中同时调用一个Lua状态下的函数是不安全的。
我正在处理同样的问题,因为在我的应用程序中,所有基础知识(如通信)都由C ++处理,所有业务逻辑都在Lua中实现。我所做的是创建一个 Lua状态池,它们都是在增量的基础上创建和初始化的(一旦没有足够的状态,创建一个并使用公共函数/对象初始化)。它的工作原理如下:
我认为这种方法也非常适合您的情况。池在上次检出时检查每个状态(以间隔为基础)。当时间差足够大时,它会破坏状态以保留资源并调整当前服务器负载的活动状态数。签出的状态是最近在可用状态中使用的状态。
在实施这样的池时,您需要考虑一些事项:
当然这只是一个想法,但结果最适合我。
答案 2 :(得分:1)
最简单的解决方案是使用lua_lock
和lua_unlock
宏进行全局锁定。这将使用由单个互斥锁锁定的单个Lua状态。对于少量的回调它可能就足够了,但是对于更高的流量,它可能不会由于产生的开销而产生。
一旦你需要更好的性能,就像W.B.提到的Lua状态池。处理这个是一个很好的方法。这里最棘手的部分我发现在多个状态中同步全局数据。
Doug提到的DarkSideSync在主应用程序循环驻留在Lua端的情况下非常有用。我专门为此目的写了它。在你的情况下,这似乎不合适。话说回来;根据您的需要,您可以考虑更改您的应用程序,以便主循环确实驻留在Lua端。如果只处理套接字,则可以使用LuaSocket,根本不需要同步。但显然这取决于应用程序的其他功能。