Я не уверен, как можно вызвать функцию Node / v8 в основном потоке Node, используя передачу событий в отдельном потоке C ++. Как можно генерировать события в потоке C ++?
Прежде чем думать о NanAsyncWorker или uv_queue_work: Я не хочу вызывать функцию C ++ в асинхронном режиме. Я хочу сделать прямо противоположное, вызывая функцию Javascript из C ++, генерируя события.
Вам не нужно использовать uv_queue_work
, но частью библиотеки потоков LibUV являются uv_async_*
методы, которые вы бы в идеале имели в этом случае. Когда вы инициализируете вторичный поток, вы также сделаете uv_async_init
создать общий async
структура данных. Эта функция также вызывается с обратным вызовом, который запускается всякий раз, когда ваш другой поток отправляет сообщение. В этом обратном вызове вы вызываете код JS для запуска ваших событий.
Вот пример полу-псевдокода:
В вашем потоке init функция вызывается из JS с единственным обратным вызовом arg:
void ThreadInit(const v8::Arguments &args){
// This is just an example, this should be saved somewhere that
// some_callback will be able to access it.
v8::Persistent<v8::Function> js_callback = args[0].As<Function>();
// And save this where you'll be able to call uv_close on it.
uv_async_t async_data;
uv_async_init(uv_default_loop(), &async_data, some_callback);
// initialize the thread and pass it async_data
}
В теме:
async_data.data = (void*) // Some data structure...
uv_async_send(&async_data);
В теме обратного вызова:
void some_callback(uv_async_t *async_data){
// Note that this depending on the data, you could easily get thread-safety issues
// here, so keep in mind that you should follow standard processes here.
void* data = async_data->data;
// Process that data however you need to in order to create a JS value, e.g.
// Using NanNew because it is more readable than standard V8.
v8::Local<Number> count = NanNew<Number>(data.count);
v8::Local<v8::Value> argv[] = {
count
};
js_callback->Call(NanNull(), 1, argv);
}