Lua中的线程本地变量

在我的应用程序中,Lua 脚本可以订阅来自客户端的某些事件。也可以让一个脚本订阅多个客户端。目前,每次调用脚本时,我都会设置全局的“Client”,以便脚本可以访问发起回调的客户端。我希望有一种像 C++ 中的线程本地变量一样的东西,这样我就可以为每个客户端创建一个新的 Lua 线程,并仅为该线程设置“Client”变量。如果客户端触发事件,则将使用与其关联的线程。

TLDR: 是否可以在 Lua 中拥有仅在特定 Lua 线程内有效的变量?

点赞
用户107090
用户107090

Lua 线程是来自单个母状态的子状态。这些 Lua 线程共享所有全局变量。

独立的 Lua 状态有独立的全局变量。

2014-06-22 23:05:22
用户3677376
用户3677376

Lua 内置没有线程局部变量,但可以为每个 Lua 线程使用一个单独的表来存储线程局部变量,并且使用 coroutine.running(或在 C 中使用 lua_pushthread)来确定哪个线程正在运行。然后使用元表使其更加方便。类似于:

local _G, coroutine = _G, coroutine
local main_thread = coroutine.running() or {} -- 返回 Lua 5.1 中的 nil
local thread_locals = setmetatable( { [main_thread]=_G }, { __mode="k" } )
local TL_meta = {}

function TL_meta:__index( k )
  local th = coroutine.running() or main_thread
  local t = thread_locals[ th ]
  if t then
    return t[ k ]
  else
    return _G[ k ]
  end
end

function TL_meta:__newindex( k, v )
  local th = coroutine.running() or main_thread
  local t = thread_locals[ th ]
  if not t then
    t = setmetatable( { _G = _G }, { __index = _G } )
    thread_locals[ th ] = t
  end
  t[ k ] = v
end

-- 通过 `TL` 表方便访问线程局部变量:
TL = setmetatable( {}, TL_meta )
-- 或将 `TL` 设置为全局查找的默认值...
if setfenv then
  setfenv( 1, TL ) -- Lua 5.1
else
  _ENV = TL -- Lua 5.2+
end
2014-06-23 04:40:51