ThreadSafeFunction

原文链接: https://github.com/nodejs/node-addon-api/blob/main/doc/threadsafe_function.md

The Napi::ThreadSafeFunction type provides APIs for threads to communicate with the addon's main thread to invoke JavaScript functions on their behalf. Documentation can be found for an overview of the API, as well as differences between the two thread-safe function APIs.


1. 方法


1.1. 构造函数


创建一个新的 Napi::ThreadSafeFunction 实例.

Napi::Function::ThreadSafeFunction();

1.2. 构造函数


创建一个新的 Napi::ThreadSafeFunction 实例.

Napi::ThreadSafeFunction::ThreadSafeFunction(napi_threadsafe_function tsfn);

当使用这个构造函数的时候, 仅能使用 Blocking(void*) / NonBlocking(void*) 重载函数; Callbackdata* 也不能使用. 参阅下文了解更多详细信息。

1.3. New


创建一个新的 Napi::ThreadSafeFunction 实例.

New 函数对于各种可选参数有几种重载:

New(napi_env env,
const Function& callback,
const Object& resource,
ResourceString resourceName,
size_t maxQueueSize,
size_t initialThreadCount,
ContextType* context,
Finalizer finalizeCallback,
FinalizerDataType* data);

返回一个非空的 Napi::ThreadSafeFunction 实例.

1.4. Acquire


向该线程安全函数对象添加一个线程,表示一个新线程将开始使用该线程安全函数。

napi_status Napi::ThreadSafeFunction::Acquire() const

返回以下结果之一:

1.5. Release


表示现有线程将停止使用此线程安全函数。线程停止使用此线程安全函数时,应调用此 API。

调用此 API 后使用任何线程安全 API 都会导致当前线程产生未定义的结果,因为当前线程可能已被销毁。

napi_status Napi::ThreadSafeFunction::Release() const

返回以下之一:

1.6. Abort


"中止" 线程安全函数。这将导致与该线程安全函数关联的所有后续 API(除 Release() 外)在其引用计数达到零之前返回 napi_closing。尤其是,BlockingCallNonBlockingCall() 将返回 napi_closing,以此来通知线程不能用线程安全函数进行异步调用。这可以用作终止线程的条件。当线程安全函数调用的返回值为 napi_closing 时,线程必须 停止使用该线程安全函数,因为不再保证 该函数会被分配。

napi_status Napi::ThreadSafeFunction::Abort() const

返回以下结果之一:

1.7. BlockingCall / NonBlockingCall

以阻塞或非阻塞方式调用 Javascript 函数。

BlockingCall()NonBlockingCall()函数对于各种可选参数有几种重载:

这些特定的函数重载只能用于通过 ThreadSafeFunction::New 创建的 ThreadSafeFunction 实例。

napi_status Napi::ThreadSafeFunction::BlockingCall(DataType* data, Callback callback) const
napi_status Napi::ThreadSafeFunction::NonBlockingCall(DataType* data, Callback callback) const

这些特定的函数重载只能用于通过 ThreadSafeFunction(napi_threadsafe_function) 创建的 ThreadSafeFunction 实例。

napi_status Napi::ThreadSafeFunction::BlockingCall(void* data) const
napi_status Napi::ThreadSafeFunction::NonBlockingCall(void* data) const

返回以下结果之一:


2. 例子


#include <chrono>
#include <thread>
#include <napi.h>
using namespace Napi;
std::thread nativeThread;
ThreadSafeFunction tsfn;
Value Start( const CallbackInfo& info ) {
Napi::Env env = info.Env();
if (info.Length() < 2) {
throw TypeError::New( env, "Expected two arguments" );
} else if (!info[0].IsFunction()) {
throw TypeError::New( env, "Expected first arg to be function" );
} else if (!info[1].IsNumber()) {
throw TypeError::New( env, "Expected second arg to be number" );
}
int count = info[1].As<Number>().Int32Value();
// Create a ThreadSafeFunction
tsfn = ThreadSafeFunction::New(
env,
info[0].As<Function>(), // JavaScript function called asynchronously
"Resource Name", // Name
0, // Unlimited queue
1, // Only one thread will use this initially
[]( Napi::Env ) { // Finalizer used to clean threads up
nativeThread.join();
}
);
// Create a native thread
nativeThread = std::thread([count] {
auto callback = []( Napi::Env env, Function jsCallback, int* value ) {
// Transform native data into JS data, passing it to the provided
// `jsCallback` -- the TSFN's JavaScript function.
jsCallback.Call( {Number::New( env, *value )} );
// We're finished with the data.
delete value;
};
for (int i = 0; i < count; i++) {
// Create new data
int* value = new int(clock());
// Perform a blocking call
napi_status status = tsfn.BlockingCall(value, callback);
if (status != napi_ok) {
// Handle error
break;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
// Release the thread-safe function
tsfn.Release();
});
return Boolean::New(env, true);
}
Napi::Object Init( Napi::Env env, Object exports ) {
exports.Set("start", Function::New( env, Start ));
return exports;
}
NODE_API_MODULE( clock, Init )

上述代码可以从 JavaScript 中使用,如下所示:

const { start } = require('bindings')('clock');
start(function () {
console.log("JavaScript callback called with arguments", Array.from(arguments));
}, 5);

执行后,输出将以一秒的间隔显示五次 clock() 的值:

JavaScript callback called with arguments [ 84745 ]
JavaScript callback called with arguments [ 103211 ]
JavaScript callback called with arguments [ 104516 ]
JavaScript callback called with arguments [ 105104 ]
JavaScript callback called with arguments [ 105691 ]
Published at:
June 18, 2025
Keywords:
node
napi