如何在C++子线程调用ArkTS方法?(线程安全)

 如何在C++子线程调用ArkTS方法?(线程安全)


HarmonyOS
2024-05-23 22:47:28
5428浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
幸运小面

napi跨线程调用,从atkts线程传下来某个函数,在c++子线程调用这个函数。

主要使用napi_create_threadsafe_function,napi_create_reference这两个接口。

相关接口:

NAPI中的线程安全函数: 
    NAPI提供的简便方法,避免了线程间通信,同时可以回到主线程调用JS函数。 
    napi_create_threadsafe_function:创建线程安全函数,也是一个NAPI对象,包含一个JS函数,可以从多个线程调用。 
  
延长生命周期: 
    从TS层传下来的函数值在对应的作用域才持有他的生命周期,超出作用域需要通过引用的方式延长他的生命周期。 
    napi_create_reference:为Object创建一个reference,以延长其生命周期。调用者需要自己管理reference生命周期。
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

参考代码:

TS侧传入回调函数

Button("跨线程调用JS函数") 
  .onClick(() => { 
    entry.threadsTest((value:number) => { 
      value += 10 
      this.cnt += 20 
      hilog.info(0x0000, 'testTag', 'js callback value = ' + value + " , cnt = " + this.cnt); 
      return value 
    }) 
  }).margin(10)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

处理从TS层传下来的函数

// 从ArkTS侧获取的参数的数量 
size_t argc = 1; 
napi_value js_cb, work_name; 
  
// 获取ArkTS参数 
napi_get_cb_info(env, info, &argc, &js_cb, nullptr, nullptr); 
  
// 指向napi_value js_cb 的 napi_ref cbObj 
napi_create_reference(env, js_cb, 1, &cbObj);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

创建线程安全函数

// 通过UTF8编码的C字符串数据创建work_name 
napi_create_string_utf8(env, "Work Item", NAPI_AUTO_LENGTH, &work_name); 
  
// 创建线程安全函数 
napi_create_threadsafe_function(env, js_cb, NULL, work_name, 0, 1, NULL, NULL, NULL, CallJs, &tsfn);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

其他线程中调用线程安全函数

// 其他线程中调用线程安全函数 
std::thread t([]() { 
    // 可获取线程ID 
    std::thread::id this_id = std::this_thread::get_id(); 
    napi_acquire_threadsafe_function(tsfn); 
    napi_call_threadsafe_function(tsfn, NULL, napi_tsfn_blocking); 
}); 
t.detach();
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

注意:启动子线程时,使用join()会等待子线程完成后继续执行,阻塞主线程;detach()会让子线程在后台执行,且结束后自动释放资源,不会阻塞主线程。

子线程回调函数

// 子线程回调 
static void CallJs(napi_env env, napi_value js_cb, void *context, void *data) 
{ 
    // 获取引用值 
    napi_get_reference_value(env, cbObj, &js_cb); 
     
    // 创建一个ArkTS number作为ArkTS function的入参。 
    napi_value argv; 
    napi_create_int32(env, cValue, &argv); 
  
    napi_value result = nullptr; 
    napi_call_function(env, nullptr, js_cb, 1, &argv, &result); 
  
    napi_get_value_int32(env, result, &cValue); 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
分享
微博
QQ
微信
回复
2024-05-24 22:21:49
相关问题
ArkTs线程方案如何保证线程安全
3564浏览 • 2回复 待解决
C++调用ArkTS 定义的方法
3413浏览 • 1回复 待解决
HarmonyOS ArkTS线程安全问题
1234浏览 • 1回复 待解决