我有一個多線程的C++插件,它做了一些後臺處理,我需要定期回調一下我在NodeJS服務器中編寫的Javascript函數。從多線程C++插件回調NodeJS Javascript函數
據我所知,這涉及到使用uv_async_send(),因爲它需要在主線程中執行,但到目前爲止我還無法弄清楚如何去做。
有沒有一個簡單的例子,我錯過了?
我有一個多線程的C++插件,它做了一些後臺處理,我需要定期回調一下我在NodeJS服務器中編寫的Javascript函數。從多線程C++插件回調NodeJS Javascript函數
據我所知,這涉及到使用uv_async_send(),因爲它需要在主線程中執行,但到目前爲止我還無法弄清楚如何去做。
有沒有一個簡單的例子,我錯過了?
最後,這是不是太困難,一旦我明白了的uv_ *函數做:
1)在插件暴露的功能,允許節點設置的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_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()
// I.e. 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
,通過我們上面的異步例如,每當我們需要做的週期性回調
uv_async_send(&async);
4)最後,當我們不再需要執行回調再以前更乾淨的東西了:
uv_close((uv_handle_t*) &async, NULL);
附錄:
自從我寫這個答案我已經遇到其他問題終於瞭解到libuv一些教訓。爲了完整起見,你應該明白:
uv_async_send
,所有 libuv功能可以僅從主循環線程調用! (我曾經看到它提到其他線程不是線程安全的,但是這太弱了)。例如,即使在主循環線程中也必須調用uv_async_init
和uv_close
。
如果您的uv_async_t
實例是動態分配的,請注意,您可能無法釋放內存,直到uv_close進行回調,讓您知道這樣做是安全的。
即:
auto async = new uv_async_t();
...
uv_close((uv_handle_t*)async, [](uv_handle_t* handle) {
delete handle;
});