检测当前线程是否是 libuv 默认事件循环的主线程

Detect whether current thread is main thread of the libuv default event loop

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

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

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

backtrace() returns a backtrace for the calling program, in the array pointed to by buffer. A backtrace is the series of currently active function calls for the program.

它的朋友,backtrace_symbols():

Given the set of addresses returned by backtrace() in buffer, backtrace_symbols() translates the addresses into an array of strings that describe the addresses symbolically. The size argument specifies the number of addresses in buffer. The symbolic representation of each address consists of the function name (if this can be determined), a hexadecimal offset into the function, and the actual return address (in hexadecimal).

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

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

我想它就像在模块初始化时从 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判断代码是否在主线程运行ning:

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";