HarmonyOS libuv实现的timer,在主线程执行没有回调,在子线程可以正常使用

#include "napi/native_api.h" 
 
#include <uv.h> 
#include <chrono> 
#include <memory> 
#include <functional> 
#include <hilog/log.h> 
 
#include <thread> 
 
  using Duration = std::chrono::nanoseconds; 
using Seconds = std::chrono::seconds; 
using Milliseconds = std::chrono::milliseconds; 
using Microseconds = std::chrono::microseconds; 
using Nanoseconds = std::chrono::nanoseconds; 
 
 
class Timer { 
  public: 
    class Impl { 
  public: 
    Impl(uv_loop_t *loop) : loop_(loop) { 
  timer_ = new uv_timer_t; 
  timer_->data = this; 
  uv_timer_init(loop_, timer_); 
} 
 
  ~Impl() { 
  uv_timer_stop(timer_); 
  uv_close(reinterpret_cast<uv_handle_t *>(timer_), 
    [](uv_handle_t *handle) { delete reinterpret_cast<uv_timer_t *>(handle); }); 
} 
 
  void start(std::chrono::milliseconds timeout, std::chrono::milliseconds repeat, 
  std::function<void()> &&callback) { 
  callback_ = std::move(callback); 
  uv_timer_start( 
  timer_, 
  [](uv_timer_t *handle) { 
  auto *impl = static_cast<Impl *>(handle->data); 
  impl->callback_(); 
}, 
timeout.count(), repeat.count()); 
} 
 
void stop() { uv_timer_stop(timer_); } 
 
private: 
  uv_loop_t *loop_; 
uv_timer_t *timer_; 
std::function<void()> callback_; 
}; 
 
Timer(uv_loop_t *loop) : mImplPtr(std::make_unique<Impl>(loop)) {} 
 
~Timer() = default; 
 
void start(std::chrono::milliseconds timeout, std::chrono::milliseconds repeat, std::function<void()> &&callback) { 
  mImplPtr->start(timeout, repeat, std::move(callback)); 
} 
 
void stop() { mImplPtr->stop(); } 
 
private: 
  std::unique_ptr<Impl> mImplPtr; 
}; 
 
void testTimerInSubThread() { 
  std::thread timerThread([]() { 
    uv_loop_t loop; 
    uv_loop_init(&loop); 
 
    Timer timer(&loop); 
    timer.start(std::chrono::milliseconds(1000), std::chrono::milliseconds(1000), 
    []() { OH_LOG_Print(LOG_APP, LOG_ERROR, 0, "timer callback", "==================="); }); 
 
    uv_run(&loop, UV_RUN_DEFAULT); 
  }); 
  timerThread.detach(); 
} 
 
void testTimerInMainThread(napi_env env) { 
  uv_loop_t* loop; 
  if (napi_ok != napi_get_uv_event_loop(env, &(loop))) { 
    throw std::runtime_error("Failed to get main loop."); 
  } 
 
  bool isActive = uv_loop_alive(loop); 
  OH_LOG_Print(LOG_APP, LOG_ERROR, 0, "loop ", "init:%{public}d\n", isActive); 
  static Timer timer(loop); 
  timer.start(Seconds::zero(), Seconds(2), 
  []() { OH_LOG_Print(LOG_APP, LOG_ERROR, 0, "timer callback", "==================="); }); 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.

主线程执行testTimerInMainThread, timer没有回调执行testTimerInSubThread可以正常回调

HarmonyOS
2024-08-03 11:04:06
浏览
收藏 0
回答 1
回答 1
按赞同
/
按时间
davis_li

主线程中此功能暂不支持,可以用以下方法代替

1. ffrt_get_main_queue()

2. ffrt_task_attr_set_queue_priority()

3. ffrt_task_attr_set_delay()

4. ffrt_queue_submit

目前只能通过ffrt的这些接口实现

分享
微博
QQ
微信
回复
2024-08-03 17:05:35
相关问题
C++时,如何阻塞TS主线程
1506浏览 • 1回复 待解决
TaskPool线程主线程如何通信
3236浏览 • 1回复 待解决
zip包解压是主线程还是IO线程
2359浏览 • 1回复 待解决