从multithreadingC ++插件callbackNodeJS Javascript函数

我有一个multithreading的C ++插件,做了一些后台处理,我需要定期callback一下我在NodeJS服务器上写的Javascript函数。

我明白,这涉及到使用uv_async_send(),因为它需要在主线程中执行,但到目前为止,我还没有能够弄清楚如何做到这一点。

有一个简单的例子,我错过了吗?

最后,一旦我了解了uv_ *函数的作用,这并不难:

1)在插件中公开一个函数,允许Node设置将被定期callback的Javascript cb:

Callback* cbPeriodic; // keep cbPeriodic somewhere NAN_METHOD(setPeriodicCb) { cbPeriodic = new Callback(info[0].As<Function>()); //... } 

2)使用uv_async_t实例初始化UV,并在我们的工作线程调用uv_async_send()时通过UV在主线程中执行该函数

 uv_async_t async; // keep this instance around for as long as we might need to do the periodic callback uv_loop_t* loop = uv_default_loop(); uv_async_init(loop, &async, asyncmsg); void asyncmsg(uv_async_t* handle) { // Called by UV in main thread after our worker thread calls uv_async_send() // Ie it's safe to callback to the CB we defined in node! Nan::HandleScope scope; v8::Isolate* isolate = v8::Isolate::GetCurrent(); Local<Value> argv[] = { v8::String::NewFromUtf8(isolate, "Hello world") }; cbPeriodic->Call(1, argv); } 

3)从工作线程调用uv_async_send ,传递上面的asynchronous实例,只要我们需要定期callback

 uv_async_send(&async); 

4)最后,当我们不再需要再次执行callback时,清理一下:

 uv_close((uv_handle_t*) &async, NULL); 

附录:

自从我写了这个答案后,我遇到了其他的问题,最后学到了关于libuv的一些教训。 为了完整,你应该明白:

  • 除了uv_async_send之外, 所有 libuv函数只能从主循环线程调用! (我曾经看到它提到其他的不是线程安全的,但是这个语句太弱了)。例如,甚至, uv_async_inituv_close必须从主循环线程调用。

  • 如果您的uv_async_t实例是dynamic分配的,请注意,您可能无法释放内存,直到uv_close进行callback,让您知道这样做是安全的。

即:

 auto async = new uv_async_t(); ... uv_close((uv_handle_t*)async, [](uv_handle_t* handle) { delete handle; });