如何在插件中从单独的c ++线程调用发射器回调? [英] How can you call an emitter callback from separate c++ thread in an addon?

查看:117
本文介绍了如何在插件中从单独的c ++线程调用发射器回调?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于上下文,我从开始问题.我需要在另一个线程中调用发射器的回调.我做了一个最小的示例,但它对emit.Call({cb, result});出现段错误我的第一个直觉是我对envemit函数的生存期存在疑问.

For context, I started with this question. I need to call the callback for the emitter in another thread. I made a minimal example but it segfaults on emit.Call({cb, result}); My first instinct is that I have a problem with the lifetimes of env or the emit function.

addon.cpp

#include <napi.h>
#include <iostream>
#include <thread>
#include <memory>
#include <functional>
#include <chrono>

std::shared_ptr<std::thread> thread;
bool running = true;

void generate(Napi::Env& env, Napi::Function& emit)
{
  while(running)
  {
    Napi::Array result = Napi::Array::New(env);

    for(int i = 0; i < 3; ++i)
    {
      result[i] = rand()%100;
    }

    auto cb = Napi::String::New(env, "onFeedData");

    emit.Call({cb, result});

    std::this_thread::sleep_for(std::chrono::seconds(1));
  }
}

Napi::Value Start(const Napi::CallbackInfo& info)
{
  Napi::Env env = info.Env();
  Napi::Function emit = info[0].As<Napi::Function>();

  auto cb = std::bind(generate, env, emit);
  thread = std::make_shared<std::thread>(cb);

  return Napi::String::New(env, "OK");
}

Napi::Value Stop(const Napi::CallbackInfo& info)
{
  Napi::Env env = info.Env();
  Napi::Function emit = info[0].As<Napi::Function>();

  running = false;
  thread->join();

  return Napi::String::New(env, "OK");
}

Napi::Object Init(Napi::Env env, Napi::Object exports)
{
  exports.Set(
      Napi::String::New(env, "Start"),
      Napi::Function::New(env, Start));

  exports.Set(Napi::String::New(env, "Stop"),
      Napi::Function::New(env, Stop));

  return exports;
}

NODE_API_MODULE(addon, Init)

index.js

'use strict'

const EventEmitter = require('events').EventEmitter;
const addon = require('./build/addon.node');

function Main() {
  const emitter = new EventEmitter();

  emitter.on('onFeedData', (evt) => {
    console.log(evt);
  })

  setTimeout(() => {
    addon.Stop( emitter.emit.bind(emitter) );
  }, 5000);

  addon.Start( emitter.emit.bind(emitter) );
}

Main();

推荐答案

我还没有尝试过,仍然知道Node.js v10.6引入了异步线程安全函数调用,它仍然在处于1级稳定性的实验状态.用法也有一定的限制,这是来自node.js文档的摘录.

I have not tried this, still I know the The node.js v10.6 has introduce Asynchronous Thread-safe Function Calls, it is still in experimental state with Stability level 1. The usage has certain limitation too, here is the snippet from the node.js documentation.

JavaScript函数通常只能从本机插件中调用 主线程.如果插件创建其他线程,则使用N-API 不需要napi_env,napi_value或napi_ref的函数 从那些线程中调用.

JavaScript functions can normally only be called from a native addon's main thread. If an addon creates additional threads, then N-API functions that require a napi_env, napi_value, or napi_ref must not be called from those threads.

当插件具有其他线程并且JavaScript函数需要 根据那些线程完成的处理来调用 线程必须与插件的主线程通信,以便主线程 线程可以代表他们调用JavaScript函数.这 线程安全函数API提供了一种简便的方法.

When an addon has additional threads and JavaScript functions need to be invoked based on the processing completed by those threads, those threads must communicate with the addon's main thread so that the main thread can invoke the JavaScript function on their behalf. The thread-safe function APIs provide an easy way to do this.

您可以从中获得有关它的完整文档. 异步线程安全函数调用

You can get the full documentation about it from. Asynchronous Thread-safe Function Calls

这篇关于如何在插件中从单独的c ++线程调用发射器回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆