【问题标题】:Is libuv thread safe?libuv线程安全吗?
【发布时间】:2012-11-30 02:39:25
【问题描述】:

我创建了一个专门用于 libuv 运行循环的新线程。线程函数看起来像这样:

void thread_function()
{
  uv_loop_t *loop = uv_loop_new();
  uv_ref( loop );
  uv_run( loop );
}

引用计数器增量使线程保持活动状态并处于处理 libuv 事件的状态。我希望能够通过在主线程上执行uv_unref来导致run loop结束,从而导致线程退出。

然而,在检查uv_ref 源代码时,我没有看到任何保证在并发访问期间对引用计数器变量的访问会同步。此外,在运行循环期间,我没有看到任何让操作系统放弃控制权的 yield 调用,这意味着程序将无法与其他进程很好地协作。

这让我相信我没有以正确的方式使用 libuv。如果有人能解释我做错了什么,那就太好了!

【问题讨论】:

    标签: c++ node.js pthreads libuv


    【解决方案1】:

    不,libuv 以这种方式不是线程安全的。您应该使用 uv_async 来指示循环退出。 uv_async 是 libuv 唯一的线程安全工具。

    看起来像这样:

    uv_async_t exit_handle;
    
    void exit_async_cb(uv_async_t* handle, int status) {
      /* After closing the async handle, it will no longer keep the loop alive. */
      uv_close((uv_handle_t*) &exit_handle, NULL);
    }
    
    void thread_function() {
      uv_loop_t *loop = uv_loop_new();
      /* The existence of the async handle will keep the loop alive. */
      uv_async_init(loop, &exit_handle, exit_async_cb);
      uv_run(loop);
    }
    

    现在,您可以从另一个线程发出信号,通过调用退出该循环

    uv_async_send(&exit_handle);
    

    您需要注意不要在其他线程完成设置循环和 uv_async 句柄之前调用uv_async_send()。最新版本的 libuv 包括您可以使用的 uv_barrier 同步原语;但 Node.js 0.8 附带的 libuv 版本尚不支持此功能,因此您可能需要使用 pthread 工具来完成此工作。

    在旁注中,您似乎正在调用 uv_refuv_unref 并使用循环引用作为参数。在最近的 libuv 版本中,这已经改变了,你现在应该 uv_refuv_unref 一个特定的句柄。详情请见uv.h

    【讨论】:

      猜你喜欢
      • 2020-04-15
      • 2011-07-04
      • 2014-04-26
      • 2010-12-30
      • 2013-03-12
      • 2021-08-03
      • 2010-12-27
      • 2018-06-04
      • 2011-09-18
      相关资源
      最近更新 更多