【问题标题】:Thread locals in LuaLua中的线程本地人
【发布时间】:2014-08-12 22:31:00
【问题描述】:

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

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

【问题讨论】:

    标签: c++ lua


    【解决方案1】:

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

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

    【讨论】:

    • 难道不能只为线程做类似 setfenv 的事情吗?
    【解决方案2】:

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-29
      • 2021-03-13
      • 1970-01-01
      • 1970-01-01
      • 2015-06-04
      • 2010-10-26
      • 1970-01-01
      • 2011-01-12
      相关资源
      最近更新 更多