线程本地人在Lua

ACB*_*ACB 2 c++ lua

在我的应用程序中,Lua脚本可以订阅来自客户端的某些事件.也可以让一个脚本订阅多个客户端.目前,我每次要调用脚本时都会设置全局"客户端",以便脚本可以访问进行回调的客户端.我想要的是类似于C++中的本地线程,这样我就可以为每个客户端创建一个新的Lua线程,并为该线程设置一次"Client"变量.如果客户端然后触发事件,它将只使用与之关联的线程.

TLDR:Lua中的变量是否可能只在特定的Lua线程中有效?

sif*_*joe 6

Lua没有内置的线程局部变量,但你可以为每个Lua线程使用一个单独的表来存储线程局部变量,并找出正在运行的线程coroutine.running(或lua_pushthread在C中).然后用metatables使它更方便.就像是:

local _G, coroutine = _G, coroutine
local main_thread = coroutine.running() or {} -- returns nil in Lua 5.1
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

-- convenient access to thread local variables via the `TL` table:
TL = setmetatable( {}, TL_meta )
-- or make `TL` the default for globals lookup ...
if setfenv then
  setfenv( 1, TL ) -- Lua 5.1
else
  _ENV = TL -- Lua 5.2+
end
Run Code Online (Sandbox Code Playgroud)