Как мне вернуть/выдать *действительно* асинхронно из C++ node-addon-api (или N-API) в Node? ⇐ C++
Как мне вернуть/выдать *действительно* асинхронно из C++ node-addon-api (или N-API) в Node?
Ситуация следующая: мой JavaScript должен запустить внешний аппаратный процесс через вызов node-addon-api в библиотеку C++. Этот аппаратный процесс выполняется неопределенное время и (каким-то образом) обрабатывается потоком библиотеки, который не имеет ничего общего с Node. После завершения внешнего процесса я хочу выполнить обратный вызов JavaScript для объекта, выполнившего начальный вызов. То, что я нашел в Интернете, было примерно таким:
#include класс MyAsyncWorker; MyAsyncWorker *gAsyncWorker{}; бул gDelete; класс MyAsyncWorker: public Napi::AsyncWorker { интервал work_units{0}; публика: MyAsyncWorker(Napi::Function& обратный вызов) : Napi::AsyncWorker(обратный вызов) {} void DoWork() { // вызывается потоком библиотеки ++рабочие_единицы; } void Execute() override { // вызывается потоком Node? в то время как (!gDelete) { если (рабочие_единицы > 50) { ВКЛ(); гDelete = правда; } else { используя пространство имен std::chrono_literals; std::this_thread::sleep_for(10ms); } } } void OnOK() переопределить { Область Napi::HandleScope(Env()); Обратный вызов().Вызов({Env().Undefine()}); } }; Napi::Value JS_start_async_worker(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); Обратный вызов Napi::Function = info[0].As(); gAsyncWorker = новый MyAsyncWorker (обратный вызов); gAsyncWorker->Очередь(); вернуть окружение.Undefine(); } bool hardware_has_data() { return std::rand() DoWork(); } еще { удалить gAsyncWorker; gAsyncWorker = nullptr; гDelete = ложь; } } } std::thread l(library_thread); Napi::Object Init(Napi::Env env, Napi::Object экспорта) { Exports.Set(Napi::String::New(env, "start_async_worker"), Napi::Function::New(env, JS_start_async_worker)); возвратный экспорт; } NODE_API_MODULE(аддон, инициализация) Отказ от ответственности: пожалуйста, не обращайте внимания на некачественные межпотоковые примитивы (если быть точным, их нет), я просто набросал их, чтобы сделать пример коротким.
JavaScript будет выглядеть примерно так:
someObject.start_async_worker(()->{ console.out("done"); }); Мой вопрос заключается в том, являются ли конструкции, касающиеся MyAsyncWorker относительно его времени жизни и безопасности потоков в Node, законными.
[*]
Можно ли мне создать AsyncWorker с глобальным временем жизни, как указано выше, или это сломается?
[*]
Насколько я понимаю этот механизм, для моего AsyncWorker::Execute() будет создан дополнительный поток, когда я передам его Node через ->Queue() . Но что, если таких асинхронных работников тысячи? Библиотека справится с этим, поскольку ей не нужны потоки для каждого из них. Как бы вы разгрузили эту нагрузку с Node?
[*]
Как правильно уничтожить объект AsyncWorker?
Ситуация следующая: мой JavaScript должен запустить внешний аппаратный процесс через вызов node-addon-api в библиотеку C++. Этот аппаратный процесс выполняется неопределенное время и (каким-то образом) обрабатывается потоком библиотеки, который не имеет ничего общего с Node. После завершения внешнего процесса я хочу выполнить обратный вызов JavaScript для объекта, выполнившего начальный вызов. То, что я нашел в Интернете, было примерно таким:
#include класс MyAsyncWorker; MyAsyncWorker *gAsyncWorker{}; бул gDelete; класс MyAsyncWorker: public Napi::AsyncWorker { интервал work_units{0}; публика: MyAsyncWorker(Napi::Function& обратный вызов) : Napi::AsyncWorker(обратный вызов) {} void DoWork() { // вызывается потоком библиотеки ++рабочие_единицы; } void Execute() override { // вызывается потоком Node? в то время как (!gDelete) { если (рабочие_единицы > 50) { ВКЛ(); гDelete = правда; } else { используя пространство имен std::chrono_literals; std::this_thread::sleep_for(10ms); } } } void OnOK() переопределить { Область Napi::HandleScope(Env()); Обратный вызов().Вызов({Env().Undefine()}); } }; Napi::Value JS_start_async_worker(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); Обратный вызов Napi::Function = info[0].As(); gAsyncWorker = новый MyAsyncWorker (обратный вызов); gAsyncWorker->Очередь(); вернуть окружение.Undefine(); } bool hardware_has_data() { return std::rand() DoWork(); } еще { удалить gAsyncWorker; gAsyncWorker = nullptr; гDelete = ложь; } } } std::thread l(library_thread); Napi::Object Init(Napi::Env env, Napi::Object экспорта) { Exports.Set(Napi::String::New(env, "start_async_worker"), Napi::Function::New(env, JS_start_async_worker)); возвратный экспорт; } NODE_API_MODULE(аддон, инициализация) Отказ от ответственности: пожалуйста, не обращайте внимания на некачественные межпотоковые примитивы (если быть точным, их нет), я просто набросал их, чтобы сделать пример коротким.
JavaScript будет выглядеть примерно так:
someObject.start_async_worker(()->{ console.out("done"); }); Мой вопрос заключается в том, являются ли конструкции, касающиеся MyAsyncWorker относительно его времени жизни и безопасности потоков в Node, законными.
[*]
Можно ли мне создать AsyncWorker с глобальным временем жизни, как указано выше, или это сломается?
[*]
Насколько я понимаю этот механизм, для моего AsyncWorker::Execute() будет создан дополнительный поток, когда я передам его Node через ->Queue() . Но что, если таких асинхронных работников тысячи? Библиотека справится с этим, поскольку ей не нужны потоки для каждого из них. Как бы вы разгрузили эту нагрузку с Node?
[*]
Как правильно уничтожить объект AsyncWorker?
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как предотвратить сортировку параметров в элементе управления SELECT в Elementor Addon
Anonymous » » в форуме Php - 0 Ответы
- 10 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Как предотвратить сортировку параметров в элементе управления SELECT в Elementor Addon
Anonymous » » в форуме Php - 0 Ответы
- 12 Просмотры
-
Последнее сообщение Anonymous
-