2015-06-16 6 views
3

Я пытаюсь реализовать расширение C++ для интеграции с node.js. Это расширение будет внутренне вызывать некоторые блокирующие вызовы, поэтому ему необходимо обеспечить неблокирующий интерфейс для мира node.js.Интеграция Node.js и C/C++: как правильно реализовать обратные вызовы?

Как указано в https://nodejs.org/api/addons.html, есть два способа реализации неблокирующих обратных вызовов:

а) с помощью простого обратного вызова функции JavaScript. Поэтому мое расширение должно было бы порождать поток и немедленно возвращаться, и пусть этот поток вызывает блокирующий код, а затем вызывает обратный вызов JavaScript при возврате. Это кажется относительно простым в реализации.

b) Используя библиотеку libuv, чтобы, если я правильно понял, отправьте событие в цикл событий node.js. Я не читал документацию libuv подробно, но это кажется довольно сложным для реализации.

Мои предпочтения, конечно, а), но я не знаю, каковы последствия. Есть ли проблема, если обратный вызов вызывается из другого потока, таким образом, cimcurventing стандартного подхода node.js к неблокирующему IO? Или libuv нужно использовать для правильной обработки потоков для моего кода и его блокирующих вызовов?

Большое спасибо за помощь.

ответ

5

Вызов обратного вызова из другого потока не является вариантом, v8 не позволяет этого. Так что вам нужно пойти с b. Это не так сложно реализовать на самом деле. Я рекомендую использовать nan для выполнения этой задачи. Вот пример из документации:

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 пул потоков и вызов обратного вызова на главном потоке.

+0

Большое спасибо, посмотрим на код. –

 Смежные вопросы

  • Нет связанных вопросов^_^