【问题标题】:Detect whether current thread is main thread of the libuv default event loop检测当前线程是否为libuv默认事件循环的主线程
【发布时间】:2015-01-30 12:58:56
【问题描述】:

我正在为 Node.js 编写一段 C 代码,并且想区分同步调用和异步调用。换句话说,我想检测我的代码是否在 V8 事件调度线程上运行,从主事件循环中调用,或者它是否从某个单独的工作线程调用。在前一种情况下,我可以立即回调 JavaScript,而在后一种情况下,我必须使用更复杂的异步回调。

libuv threading API 提供 uv_thread_self 来识别当前线程,并提供 uv_thread_equal 来比较线程是否相等。所以我只需要找到主事件循环的uv_thread_t

【问题讨论】:

  • 我很困惑怎么可能有不知道它在哪个线程上运行的代码。任何回调都将在排队的同一线程上运行,并且 libuv 无论如何都不是线程安全的,因此您不能将来自不是事件循环线程的线程的回调排队。
  • 我正在处理libxslt extension functions。因此,我正在编写 C 代码,该代码将注册到 XSLT 库的全局数据结构中,并且将从 XSLT 处理器中调用,而 XSLT 处理器又可以同步或异步调用。目前我最好的选择是在函数注册时从uv_thread_self 保存结果,假设它始终是主事件循环线程。但我仍然想知道是否还有比这更优雅的东西。

标签: c node.js multithreading event-loop libuv


【解决方案1】:

我想它就像在模块初始化中从 v8 线程中获取 uv_thread_self() 一样简单(正如你提到的你使用 node.js)? 该模块初始化代码应该从主 v8 线程运行,因为这是来自您的库的 Javascript 包的require()

uv_thread_t main_thread;

extern "C" void init(Handle<Object> target, Handle<Object> module) {

    Nan::HandleScope scope;

    main_thread = uv_thread_self();

那么你可以使用uv_thread_equal来判断代码是否在主线程中运行:

void ozw_watcher_callback(OpenZWave::Notification const *cb, void *ctx)
// ===================================================================
{
    uv_thread_t this_thread = uv_thread_self();
    std::cout << "~~~~ ozw_watcher_callback : main thread? " << (uv_thread_equal(&main_thread, &this_thread)) << "\n";

【讨论】:

    【解决方案2】:

    在 Linux(可能还有 MacOS 和 Solaris)上,您可以查看backtrace()

    backtrace() 在数组中返回调用程序的回溯 由buffer 指向。回溯是当前活动的系列 程序的函数调用。

    它是朋友,backtrace_symbols():

    给定缓冲区中backtrace()返回的地址集, backtrace_symbols() 将地址转换为字符串数组 象征性地描述地址。大小参数指定 缓冲区中的地址数。每个符号的表示 address 由函数名组成(如果可以确定的话),a 函数的十六进制偏移量,以及实际的返回地址 (十六进制)。

    http://linux.die.net/man/3/backtrace

    在 Windows 上,我认为以下问题显示了如何实现类似的功能: http://bewitchingkitchen.com/2010/01/30/slow-roasted-chicken-thighs-an-ice-breaker/

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-02
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-13
    相关资源
    最近更新 更多