我正在为节点构建一个本机扩展,其中包括一个长时间运行的操作,并在完成时回调。
我正在将一个节点缓冲区传递给该调用。它包含扩展名要处理的内容的有效负载。
我应该能够将我的缓冲区存储在AsyncWorker的构造函数中的持久存储中,并在以后需要时检索它。
这个例子(来自nan测试套件)是我通常基于我的代码:https://github.com/nodejs/nan/blob/master/test/cpp/bufferworkerpersistent.cpp
这个测试有效,但是在HandleOKCallback方法之前它对缓冲区没有任何作用,这对我来说并不是很有趣。我需要在Execute方法期间访问缓冲区。
如果我只是在测试的Execute()方法中添加一行来尝试访问缓冲区,如下所示:
void Execute () {
printf("before GetFromPersistent\n");
v8::Local<v8::Value> handle = GetFromPersistent("buffer");
printf("after GetFromPersistent\n");
printf("buffer @%llux len %ld\n", (uint64_t)node::Buffer::Data(handle), node::Buffer::Length(handle));
Sleep(milliseconds);
}
我在GetFromPersistent调用上遇到了段错误。
我的问题是:我错过了什么?我是否应该无法将持久对象拉入Execute方法?如果是这样,为什么不呢?
答案 0 :(得分:3)
好的,我认为答案是&#34; duh&#34;,但对于其他人刚刚开始使用Node原生扩展,我现在理解的是:
由于node是单个线程,因此长时间运行的任务必须在不同的线程中运行才能阻止节点。
Nan使用libuv来管理线程池,以执行您在&#34; Execute&#34;中执行的异步工作。方法
但是,AsyncWorker的构造函数实际上是在节点的线程上运行的,而HandleOKCallback也会在Execute完成后安排在那里运行。
所以在构造函数和回调设置中访问节点资源是可以的,但是由于Execute在另一个线程上运行它不行,所以它会出错。
因此,对于我的问题(我在AsyncWorker中运行JPEG解码),我反而将指针和长度从构造函数中的缓冲区中拉出来,但仍然在缓冲区上调用SaveToPersistent,所以它没有&#39当我解码这些位时,我得到了GC。