Я пытаюсь реализовать расширение C ++ для интеграции с node.js. Это расширение будет внутренне вызывать некоторые блокирующие вызовы, поэтому оно должно обеспечить неблокирующий интерфейс для мира node.js.
Как указано в https://nodejs.org/api/addons.html, Есть два способа реализовать неблокирующие обратные вызовы:
а) С помощью простого обратного вызова функции JavaScript. Таким образом, мое расширение должно было бы порождать поток и немедленно возвращаться, и позволить этому потоку вызвать блокирующий код, а затем вызвать обратный вызов JavaScript по возвращении. Это кажется относительно простым для реализации.
б) Используя библиотеку libuv, чтобы, если я правильно понял, опубликовать событие в цикле событий node.js. Я не читал документацию libuv подробно, но это кажется довольно сложным для реализации.
Я предпочитаю, конечно, а), но я понятия не имею, каковы последствия. Есть ли какая-либо проблема, если обратный вызов вызывается из другого потока, таким образом, cimcurventing стандартный подход node.js для неблокирующей IO? Или нужно использовать libuv для правильной обработки потоков для моего кода и его вызовов блокировки?
Большое спасибо за Вашу помощь.
Вызов обратного вызова из другого потока не вариант, v8 не позволяет этого. Таким образом, вы должны пойти с б. Это не так сложно реализовать на самом деле. Я рекомендую использовать бабушка для этой задачи. Вот пример из документации:
class PiWorker : public NanAsyncWorker {
public:
PiWorker(NanCallback *callback, int points)
: NanAsyncWorker(callback), points(points) {}
~PiWorker() {}
// Executed inside the worker-thread.
// It is not safe to access V8, or V8 data structures
// here, so everything we need for input and output
// should go on `this`.
void Execute () {
estimate = Estimate(points);
}
// Executed when the async work is complete
// this function will be run inside the main event loop
// so it is safe to use V8 again
void HandleOKCallback () {
NanScope();
Local<Value> argv[] = {
NanNull()
, NanNew<Number>(estimate)
};
callback->Call(2, argv);
};
private:
int points;
double estimate;
};
// Asynchronous access to the `Estimate()` function
NAN_METHOD(CalculateAsync) {
NanScope();
int points = args[0]->Uint32Value();
NanCallback *callback = new NanCallback(args[1].As<Function>());
NanAsyncQueueWorker(new PiWorker(callback, points));
NanReturnUndefined();
}
Он будет обрабатывать вызов вашего кода с использованием пула потоков libuv и обратный вызов в основном потоке.