Node.js C++ Addon 多线程示例:异步执行任务
以下是一个简单的 Node.js C++ addon 多线程示例,演示了如何使用多线程来执行异步任务:
#include <node.h>
#include <uv.h>
#include <iostream>
#include <thread>
namespace addon {
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::NewStringType;
using v8::Object;
using v8::String;
using v8::Value;
// 用于异步执行的工作结构体
struct Work {
uv_work_t request;
int input;
int result;
Isolate* isolate;
// 可以添加其他需要的参数
};
// 工作完成后的回调函数
void WorkCallback(uv_work_t* req, int status) {
Isolate* isolate = reinterpret_cast<Work*>(req->data)->isolate;
Local<String> result =
String::NewFromUtf8(isolate, std::to_string(reinterpret_cast<Work*>(req->data)->result).c_str(), NewStringType::kNormal).ToLocalChecked();
// 在主线程上执行回调函数
const unsigned argc = 1;
Local<Value> argv[argc] = { result };
Local<Function> callback = Local<Function>::Cast(reinterpret_cast<Work*>(req->data)->request.data);
callback->Call(isolate->GetCurrentContext(), Null(isolate), argc, argv);
delete reinterpret_cast<Work*>(req->data);
}
// 工作函数,用于执行耗时任务
void DoWork(Work* work) {
// 执行任务,例如计算输入值的平方
work->result = work->input * work->input;
// 可以添加其他需要的操作,例如线程间通信
}
// Node.js addon 的函数实现
void AsyncWork(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Function> callback = Local<Function>::Cast(args[1]);
// 创建异步工作结构体
Work* work = new Work();
work->request.data = reinterpret_cast<void*>(callback);
work->input = args[0]->NumberValue(isolate);
work->isolate = isolate;
// 在另一个线程上执行任务
std::thread t(DoWork, work);
t.detach();
// 在主线程上返回空值
args.GetReturnValue().SetUndefined();
}
// 初始化 addon
void Init(Local<Object> exports) {
NODE_SET_METHOD(exports, 'asyncWork', AsyncWork);
}
NODE_MODULE(NODE_GYP_MODULE_NAME, Init)
}
在上面的示例中,我们定义了一个 'Work' 结构体,用于存储异步执行需要的参数,例如输入值和计算结果。
我们使用 uv_work_t 和 uv_queue_work 函数来执行异步工作。在 AsyncWork 函数中,我们创建一个新的 'Work' 结构体,并将回调函数传递给 request.data。然后,我们创建一个新的线程,并在该线程上执行 DoWork 函数,该函数执行耗时任务。执行完成后,我们在工作完成的回调函数 WorkCallback 中调用回调函数,并将计算结果作为参数传递给它。
最后,我们将该 addon 初始化函数 Init 导出为 NODE_MODULE,并在其中定义我们的 asyncWork 函数。
在 Node.js 中,我们可以通过以下方式调用该 addon:
const addon = require('./build/Release/addon.node');
addon.asyncWork(10, (result) => {
console.log(result); // 输出 100
});
在调用 addon.asyncWork 函数时,我们传递了一个输入值 10 和一个回调函数。在工作完成后,该回调函数将会被调用,并输出计算得到的结果 100。注意,由于工作是在另一个线程中执行的,因此在输出结果之前,可以执行其他任何任务。
原文地址: https://www.cveoy.top/t/topic/ok4Z 著作权归作者所有。请勿转载和采集!