调用一些callback函数会导致分段错误:Nan
我正在用nbind编写C ++插件- GitHub链接用于大多数事情,而Nan-GitHub链接用于调用asynchronouscallback。 当我只调用callback一次,它的作品完美。 但是,当我调用callback两次,它给Segmentation fault (core dumped)
。 使用gdb
找不到错误。 这里是JS和C ++代码(使用node-gyp configure build
编译):
//main.js code var nbind = require('nbind'); var lib = nbind.init().lib; lib.HeaderExample.callJS(function(a) { console.log("result" + a); }); lib.HeaderExample.startThread(); lib.HeaderExample.startThread();
C ++插件的代码
//c++ code class CallbackRunner : public Nan::AsyncWorker { public: CallbackRunner(Nan::Callback *callback) : AsyncWorker(callback) {} void Execute () {} void HandleOKCallback () { std::cout << "running HandleOKCallback in thread " << std::this_thread::get_id() << std::endl; Nan::HandleScope scope; v8::Local<v8::Value> argv[] = { Nan::New<v8::Number>(10) }; callback->Call(1, argv); } }; class HeaderExample { public: static void callJS(nbind::cbFunction &callback) { std::cout << "running callJS in thread " << std::this_thread::get_id() << std::endl; m_onInitialisationStarted = new nbind::cbFunction(callback); Nan::Callback *callbackNan = new Nan::Callback(m_onInitialisationStarted->getJsFunction()); runner = new CallbackRunner(callbackNan); } static void startThread() { std::cout << "it is here"; std::thread threadS(some); threadS.join(); } static void some() { std::cout << "running some in thread: " << std::this_thread::get_id() << std::endl; if(runner){ AsyncQueueWorker(runner); } } inline static nbind::cbFunction *m_onInitialisationStarted = 0; inline static CallbackRunner *runner; };
您的类使用AsyncQueueWorker
调用CallbackRunner
,但AsyncQueueWorker
在callback完成后调用AsyncExecuteComplete
,而这又调用worker->Destroy()
。 请参阅AsyncQueueWorker
代码:
inline void AsyncExecute (uv_work_t* req) { AsyncWorker *worker = static_cast<AsyncWorker*>(req->data); worker->Execute(); } inline void AsyncExecuteComplete (uv_work_t* req) { AsyncWorker* worker = static_cast<AsyncWorker*>(req->data); worker->WorkComplete(); worker->Destroy(); } inline void AsyncQueueWorker (AsyncWorker* worker) { uv_queue_work( uv_default_loop() , &worker->request , AsyncExecute , reinterpret_cast<uv_after_work_cb>(AsyncExecuteComplete) ); }
worker->Destroy()
将删除CallbackRunner
类以及您提供给其构造函数的Nan::Callback
。 这就是为什么当您尝试再次调用此callback时出现分段错误的原因。
你可能更好的基于你的类Nan::AsyncProgressQueueWorker
而不是Nan::AsyncWorker
。 AsyncProgressQueueWorker
inheritance了AsyncWorker
,它允许您像AsyncWorker
一样从主线程安排工作,但是它提供了一个ExecutionProgress
类,允许您使用任何线程在原始的计划工作中任意次数地调用主线程在跑。
在版本2.8.0
Nan::AsyncProgressQueueWorker
被添加到了NAN中
您不能有两个线程同时调用同一个V8实例。 您需要小心locking,以确保在任何时候只有一个线程与V8交互。