- assert 断言
- async_hooks 异步钩子
- async_hooks/context 异步上下文
- buffer 缓冲区
- C++插件
- C/C++插件(使用Node-API)
- C++嵌入器
- child_process 子进程
- cluster 集群
- CLI 命令行
- console 控制台
- Corepack 核心包
- crypto 加密
- crypto/webcrypto 网络加密
- debugger 调试器
- deprecation 弃用
- dgram 数据报
- diagnostics_channel 诊断通道
- dns 域名服务器
- domain 域
- Error 错误
- events 事件触发器
- fs 文件系统
- global 全局变量
- http 超文本传输协议
- http2 超文本传输协议2.0
- https 安全超文本传输协议
- inspector 检查器
- Intl 国际化
- module 模块
- module/cjs CommonJS模块
- module/esm ECMAScript模块
- module/package 包模块
- net 网络
- os 操作系统
- path 路径
- perf_hooks 性能钩子
- permission 权限
- process 进程
- punycode 域名代码
- querystring 查询字符串
- readline 逐行读取
- repl 交互式解释器
- report 诊断报告
- sea 单个可执行应用程序
- stream 流
- stream/web 网络流
- string_decoder 字符串解码器
- test 测试
- timers 定时器
- tls 安全传输层
- trace_events 跟踪事件
- tty 终端
- url 网址
- util 实用工具
- v8 引擎
- vm 虚拟机
- wasi 网络汇编系统接口
- worker_threads 工作线程
- zlib 压缩
Node.js v20.3.1 文档
- Node.js v20.3.1
-
►
目录
- Node-API
- ABI 稳定性的影响
- 构建
- 使用方法
- Node-API 版本矩阵
- 环境生命周期 API
- 基本的 Node-API 数据类型
- 错误处理
- 对象生命周期管理
- 模块注册
- 使用 JavaScript 值
- 枚举类型
- 对象创建函数
napi_create_arraynapi_create_array_with_lengthnapi_create_arraybuffernapi_create_buffernapi_create_buffer_copynapi_create_datenapi_create_externalnapi_create_external_arraybuffernapi_create_external_buffernapi_create_objectnapi_create_symbolnode_api_symbol_fornapi_create_typedarraynapi_create_dataview
- 从 C 类型转换为 Node-API 的函数
- 从 Node-API 转换为 C 类型的函数
napi_get_array_lengthnapi_get_arraybuffer_infonapi_get_buffer_infonapi_get_prototypenapi_get_typedarray_infonapi_get_dataview_infonapi_get_date_valuenapi_get_value_boolnapi_get_value_doublenapi_get_value_bigint_int64napi_get_value_bigint_uint64napi_get_value_bigint_wordsnapi_get_value_externalnapi_get_value_int32napi_get_value_int64napi_get_value_string_latin1napi_get_value_string_utf8napi_get_value_string_utf16napi_get_value_uint32
- 获取全局实例的函数
- 使用 JavaScript 值和抽象操作
- 使用 JavaScript 属性
- 结构
- 函数
napi_get_property_namesnapi_get_all_property_namesnapi_set_propertynapi_get_propertynapi_has_propertynapi_delete_propertynapi_has_own_propertynapi_set_named_propertynapi_get_named_propertynapi_has_named_propertynapi_set_elementnapi_get_elementnapi_has_elementnapi_delete_elementnapi_define_propertiesnapi_object_freezenapi_object_seal
- 使用 JavaScript 函数
- 对象封装
- 简单的异步操作
- 自定义异步操作
- 版本管理
- 内存管理
- Promise
- 脚本执行
- libuv 事件循环
- 异步线程安全函数调用
- 其他实用工具
- Node-API
-
►
导航
- assert 断言
- async_hooks 异步钩子
- async_hooks/context 异步上下文
- buffer 缓冲区
- C++插件
- C/C++插件(使用Node-API)
- C++嵌入器
- child_process 子进程
- cluster 集群
- CLI 命令行
- console 控制台
- Corepack 核心包
- crypto 加密
- crypto/webcrypto 网络加密
- debugger 调试器
- deprecation 弃用
- dgram 数据报
- diagnostics_channel 诊断通道
- dns 域名服务器
- domain 域
- Error 错误
- events 事件触发器
- fs 文件系统
- global 全局变量
- http 超文本传输协议
- http2 超文本传输协议2.0
- https 安全超文本传输协议
- inspector 检查器
- Intl 国际化
- module 模块
- module/cjs CommonJS模块
- module/esm ECMAScript模块
- module/package 包模块
- net 网络
- os 操作系统
- path 路径
- perf_hooks 性能钩子
- permission 权限
- process 进程
- punycode 域名代码
- querystring 查询字符串
- readline 逐行读取
- repl 交互式解释器
- report 诊断报告
- sea 单个可执行应用程序
- stream 流
- stream/web 网络流
- string_decoder 字符串解码器
- test 测试
- timers 定时器
- tls 安全传输层
- trace_events 跟踪事件
- tty 终端
- url 网址
- util 实用工具
- v8 引擎
- vm 虚拟机
- wasi 网络汇编系统接口
- worker_threads 工作线程
- zlib 压缩
- ► 其他版本
异步线程安全函数调用#
JavaScript 函数通常只能从原生插件的主线程调用。 如果插件创建了额外的线程,则不得从这些线程调用需要 napi_env、napi_value 或 napi_ref 的 Node-API 函数。
当插件有额外的线程并且需要根据这些线程完成的处理调用 JavaScript 函数时,这些线程必须与插件的主线程通信,以便主线程可以代表它们调用 JavaScript 函数。 线程安全函数 API 提供了一种简单的方法来执行此操作。
这些 API 提供了类型 napi_threadsafe_function 以及创建、销毁和调用该类型对象的 API。
napi_create_threadsafe_function() 创建对 napi_value 的持久引用,该引用包含可从多个线程调用的 JavaScript 函数。 调用异步发生。 这意味着调用 JavaScript 回调的值将被放置在一个队列中,并且对于队列中的每个值,最终将调用 JavaScript 函数。
创建 napi_threadsafe_function 后,可以提供 napi_finalize 回调。 当线程安全函数即将被销毁时,将在主线程上调用此回调。 它接收构造期间给出的上下文和最终数据,并提供在线程之后进行清理的机会,例如 通过调用 uv_thread_join()。 除了主循环线程之外,在 finalize 回调完成后,没有线程应该使用线程安全函数。
在调用 napi_create_threadsafe_function() 期间给出的 context 可以从调用 napi_get_threadsafe_function_context() 的任何线程中检索。
调用线程安全的函数#
napi_call_threadsafe_function() 可用于启动对 JavaScript 的调用。 napi_call_threadsafe_function() 接受一个参数,该参数控制 API 是否以阻塞方式运行。 如果设置为 napi_tsfn_nonblocking,API 将以非阻塞方式运行,如果队列已满则返回 napi_queue_full,从而阻止数据成功添加到队列中。 如果设置为 napi_tsfn_blocking,API 将阻塞,直到队列中有可用空间。
如果创建的线程安全函数的最大队列大小为 0,则 napi_call_threadsafe_function() 永远不会阻塞。
不应从 JavaScript 线程使用 napi_tsfn_blocking 调用 napi_call_threadsafe_function(),因为如果队列已满,可能会导致 JavaScript 线程死锁。
对 JavaScript 的实际调用由通过 call_js_cb 参数给出的回调控制。 对于通过成功调用 napi_call_threadsafe_function() 放入队列中的每个值,在主线程上调用 call_js_cb 一次。 如果没有给出这样的回调,将使用默认回调,并且生成的 JavaScript 调用将没有参数。
call_js_cb 回调在其参数中接收要作为 napi_value 调用的 JavaScript 函数,以及创建 napi_threadsafe_function 时使用的 void* 上下文指针,以及由其中一个辅助线程创建的下一个数据指针。 然后,回调可以使用诸如 napi_call_function() 之类的 API 来调用 JavaScript。
回调也可以在 env 和 call_js_cb 都设置为 NULL 的情况下调用,以指示不再可能调用 JavaScript,而项目仍保留在可能需要释放的队列中。 这通常发生在 Node.js 进程退出而线程安全功能仍处于活动状态时。
没有必要通过 napi_make_callback() 调用 JavaScript,因为 Node-API 在适合回调的上下文中运行 call_js_cb。
线程安全函数的引用计数#
在 napi_threadsafe_function 对象存在期间,可以将线程添加到 napi_threadsafe_function 对象或从中删除。 因此,除了在创建时指定线程的初始数量外,还可以调用 napi_acquire_threadsafe_function 来指示新线程将开始使用线程安全函数。
同样,可以调用 napi_release_threadsafe_function 来指示现有线程将停止使用线程安全函数。
当使用该对象的每个线程调用 napi_release_threadsafe_function() 或收到 napi_closing 的返回状态以响应对 napi_call_threadsafe_function 的调用时,napi_threadsafe_function 对象将被销毁。 在 napi_threadsafe_function 被销毁之前队列被清空。 napi_release_threadsafe_function() 应该是与给定的 napi_threadsafe_function 一起进行的最后一次 API 调用,因为在调用完成后,无法保证 napi_threadsafe_function 仍然被分配。 出于同样的原因,在收到 napi_closing 的返回值以响应对 napi_call_threadsafe_function 的调用后,不要使用线程安全函数。 可以在传递给 napi_create_threadsafe_function() 的 napi_finalize 回调中释放与 napi_threadsafe_function 关联的数据。 napi_create_threadsafe_function 的参数 initial_thread_count 表示线程安全函数的初始获取次数,而不是在创建时多次调用 napi_acquire_threadsafe_function。
一旦使用 napi_threadsafe_function 的线程数达到零,则没有其他线程可以通过调用 napi_acquire_threadsafe_function() 开始使用它。 事实上,除 napi_release_threadsafe_function() 之外的所有后续 API 调用都将返回错误值 napi_closing。
线程安全函数可以通过给 napi_release_threadsafe_function() 赋值 napi_tsfn_abort 来实现 "aborted"。 这将导致除 napi_release_threadsafe_function() 之外与线程安全函数关联的所有后续 API 甚至在其引用计数达到零之前就返回 napi_closing。 特别是,napi_call_threadsafe_function() 将返回 napi_closing,从而通知线程不再可能对线程安全函数进行异步调用。 这可以用作终止线程的标准。 从 napicallthreadsafefunction() 接收到 napiclosing 的返回值后,线程不得再使用线程安全函数,因为不再保证会分配它。
决定是否保持进程运行#
与 libuv 句柄类似,线程安全函数可以是 "referenced" 和 "unreferenced"。 "referenced" 线程安全函数将导致创建它的线程上的事件循环保持活动状态,直到线程安全函数被销毁。 相反,"unreferenced" 线程安全函数不会阻止事件循环退出。 API napi_ref_threadsafe_function 和 napi_unref_threadsafe_function 就是为此目的而存在的。
napi_unref_threadsafe_function 既没有将线程安全函数标记为可以被销毁,也没有 napi_ref_threadsafe_function 阻止它被销毁。
napi_create_threadsafe_function#
NAPI_EXTERN napi_status
napi_create_threadsafe_function(napi_env env,
napi_value func,
napi_value async_resource,
napi_value async_resource_name,
size_t max_queue_size,
size_t initial_thread_count,
void* thread_finalize_data,
napi_finalize thread_finalize_cb,
void* context,
napi_threadsafe_function_call_js call_js_cb,
napi_threadsafe_function* result);
[in] env: 调用 API 的环境。[in] func: 从另一个线程调用的可选 JavaScript 函数。 如果NULL传递给call_js_cb,则必须提供它。[in] async_resource: 与将传递给可能的async_hooksinit钩子 的异步工作关联的可选对象。[in] async_resource_name: 一个 JavaScript 字符串,用于为async_hooksAPI 公开的诊断信息提供的资源类型提供标识符。[in] max_queue_size: 队列的最大大小。0为无限制。[in] initial_thread_count: 初始获取数,即初始线程数,包括将使用此函数的主线程。[in] thread_finalize_data: 要传递给thread_finalize_cb的可选数据。[in] thread_finalize_cb:napi_threadsafe_function被销毁时调用的可选函数。[in] context: 附加到生成的napi_threadsafe_function的可选数据。[in] call_js_cb: 可选回调调用 JavaScript 函数以响应不同线程上的调用。 此回调将在主线程上调用。 如果没有给出,JavaScript 函数将在没有参数的情况下调用,并将undefined作为其this值。napi_threadsafe_function_call_js提供了更多详细信息。[out] result: 异步线程安全的 JavaScript 函数。
napi_get_threadsafe_function_context#
NAPI_EXTERN napi_status
napi_get_threadsafe_function_context(napi_threadsafe_function func,
void** result);
[in] func: 为其检索上下文的线程安全函数。[out] result: 存储上下文的位置。
可以从使用 func 的任何线程调用此 API。
napi_call_threadsafe_function#
NAPI_EXTERN napi_status
napi_call_threadsafe_function(napi_threadsafe_function func,
void* data,
napi_threadsafe_function_call_mode is_blocking);
[in] func: 要调用的异步线程安全 JavaScript 函数。[in] data: 通过创建线程安全 JavaScript 函数期间提供的回调call_js_cb发送到 JavaScript 的数据。[in] is_blocking: 标志,其值可以是napi_tsfn_blocking,表示如果队列已满,调用应该阻塞;也可以是napi_tsfn_nonblocking,表示只要队列已满,调用就应该立即返回,状态为napi_queue_full。
不应从 JavaScript 线程使用 napi_tsfn_blocking 调用此 API,因为如果队列已满,可能会导致 JavaScript 线程死锁。
如果从任何线程调用 napi_release_threadsafe_function() 并将 abort 设置为 napi_tsfn_abort,则此 API 将返回 napi_closing。 只有当 API 返回 napi_ok 时,该值才会添加到队列中。
可以从使用 func 的任何线程调用此 API。
napi_acquire_threadsafe_function#
NAPI_EXTERN napi_status
napi_acquire_threadsafe_function(napi_threadsafe_function func);
[in] func: 开始使用异步线程安全的 JavaScript 函数。
线程应在将 func 传递给任何其他线程安全函数 API 以指示它将使用 func 之前调用此 API。 这可以防止 func 在所有其他线程停止使用它时被销毁。
可以从将开始使用 func 的任何线程调用此 API。
napi_release_threadsafe_function#
NAPI_EXTERN napi_status
napi_release_threadsafe_function(napi_threadsafe_function func,
napi_threadsafe_function_release_mode mode);
[in] func: 异步线程安全的 JavaScript 函数,其引用计数将减少。[in] mode: 其值可以是napi_tsfn_release的标志,表示当前线程将不再调用线程安全函数,或者是napi_tsfn_abort,表示除了当前线程之外,没有其他线程应该进一步调用线程安全函数 功能。 如果设置为napi_tsfn_abort,对napi_call_threadsafe_function()的进一步调用将返回napi_closing,并且不会将更多值放入队列中。
线程停止使用 func 时应调用此 API。 在调用此 API 后将 func 传递给任何线程安全的 API 会产生未定义的结果,因为 func 可能已被销毁。
可以从任何将停止使用 func 的线程调用此 API。
napi_ref_threadsafe_function#
NAPI_EXTERN napi_status
napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func);
[in] env: 调用 API 的环境。[in] func: 要引用的线程安全函数。
此 API 用于指示在主线程上运行的事件循环在 func 被销毁之前不应退出。 与 uv_ref 类似,它也是幂等的。
napi_unref_threadsafe_function 既没有将线程安全函数标记为可以被销毁,也没有 napi_ref_threadsafe_function 阻止它被销毁。 napi_acquire_threadsafe_function 和 napi_release_threadsafe_function 可用于该目的。
此 API 只能从主线程调用。
napi_unref_threadsafe_function#
NAPI_EXTERN napi_status
napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func);
[in] env: 调用 API 的环境。[in] func: 要取消引用的线程安全函数。
该 API 用于指示在主线程上运行的事件循环可能会在 func 被销毁之前退出。 与 uv_unref 类似,它也是幂等的。
此 API 只能从主线程调用。