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

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


HarmonyOS
2024-05-23 22:47:28
浏览
收藏 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生命周期。

参考代码:

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)

处理从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);

创建线程安全函数

// 通过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);

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

// 其他线程中调用线程安全函数 
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();

注意:启动子线程时,使用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); 
}
分享
微博
QQ
微信
回复
2024-05-24 22:21:49
相关问题
ArkTs线程方案如何保证线程安全
2420浏览 • 1回复 待解决
C++调用ArkTS 定义的方法
1759浏览 • 1回复 待解决
如何在进行并发操作时保证线程安全
247浏览 • 1回复 待解决
HarmonyOS ArkTS线程安全问题
326浏览 • 1回复 待解决
如何在Worker中开启多级线程
258浏览 • 1回复 待解决
如何在C/C++ 创建ArkTS的对象
2088浏览 • 1回复 待解决
TaskPool线程和主线程如何通信
2249浏览 • 1回复 待解决
C++回调时,如何阻塞TS主线程
376浏览 • 1回复 待解决