节点NAN:在AsyncWorker

时间:2015-12-09 04:39:55

标签: node.js asynchronous v8 node.js-addon node.js-nan

我正在为节点构建一个本机扩展,其中包括一个长时间运行的操作,并在完成时回调。

我正在将一个节点缓冲区传递给该调用。它包含扩展名要处理的内容的有效负载。

我应该能够将我的缓冲区存储在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方法?如果是这样,为什么不呢?

1 个答案:

答案 0 :(得分:3)

好的,我认为答案是&#34; duh&#34;,但对于其他人刚刚开始使用Node原生扩展,我现在理解的是:

由于node是单个线程,因此长时间运行的任务必须在不同的线程中运行才能阻止节点。

Nan使用libuv来管理线程池,以执行您在&#34; Execute&#34;中执行的异步工作。方法

但是,AsyncWorker的构造函数实际上是在节点的线程上运行的,而HandleOKCallback也会在Execute完成后安排在那里运行。

所以在构造函数和回调设置中访问节点资源是可以的,但是由于Execute在另一个线程上运行它不行,所以它会出错。

因此,对于我的问题(我在AsyncWorker中运行JPEG解码),我反而将指针和长度从构造函数中的缓冲区中拉出来,但仍然在缓冲区上调用SaveToPersistent,所以它没有&#39当我解码这些位时,我得到了GC。