C++实现仿安卓线程Handler、Message、Looper的功能

[复制链接]
发表于 2026-1-1 19:52:56 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
在java开发中,风俗使用Handler、Message来处置惩罚同步,比如对相机的利用(open、setParamters、start、stop、clost)全部抛到同一个线程处置惩罚,防止并发利用导致非常,如许保存给外部的同一接口就是安全的,无论外部哪些线程来调用,终极到控制模块都是在同一线程处置惩罚相机利用。这里提供一个C++实现的Handler Message封装,可以实现类似安卓那样的接口;
Handler类封装:
  1. #ifndef _CPP_THREADHANDLER_H
  2. #define _CPP_THREADHANDLER_H
  3. #include <algorithm>
  4. #include <chrono>
  5. #include <condition_variable>
  6. #include <functional>
  7. #include <iostream>
  8. #include <list>
  9. #include <map>
  10. #include <memory>
  11. #include <mutex>
  12. #include <thread>
  13. #include "Message.h"
  14. class ThreadHandler {
  15.    public:
  16.     using TimePoint_t = std::chrono::steady_clock::time_point;
  17.     using Clock_t = std::chrono::steady_clock;
  18.     using MillisDuration_t = std::chrono::milliseconds;
  19.     using Task = std::function<void(const Message& msg)>;
  20.     ThreadHandler() : _stoped(false) { initLoop(); }
  21.     ~ThreadHandler() {
  22.         _stoped = true;
  23.         _cond.notify_all();
  24.         _looper.join();
  25.     }
  26.     void setName(const std::string n) { this->name = n; }
  27.     bool sendEmptyMessageDelay(int what, long delay_millis) {
  28.         if (what < 0 || delay_millis < 0)
  29.             return false;
  30.         Message msg(what, delay_millis);
  31.         std::unique_lock<std::mutex> lock(_queue_lock);
  32.         _msg_list.push_back(msg);
  33.         _msg_list.sort(std::less<Message>());
  34.         _cond.notify_all();
  35.         return true;
  36.     }
  37.     bool sendEmptyMessageDelay(int what) {
  38.         return sendEmptyMessageDelay(what, 0);
  39.     }
  40.     bool postDelay(std::function<void()>&& f, long delay_millis) {
  41.         if (f == nullptr || delay_millis < 0) {
  42.             return false;
  43.         }
  44.         std::unique_lock<std::mutex> lock(_queue_lock);
  45.         Message msg(0, delay_millis);
  46.         msg.onRun(std::move(f));
  47.         _msg_list.push_back(msg);
  48.         _msg_list.sort(std::less<Message>());
  49.         _cond.notify_all();
  50.         return true;
  51.     }
  52.     bool post(std::function<void()>&& f) { return postDelay(std::move(f), 0); }
  53.     void removeMessages(int what) {
  54.         if (what < 0)
  55.             return;
  56.         std::unique_lock<std::mutex> lock(_queue_lock);
  57.         if (!_msg_list.empty())
  58.             _msg_list.remove_if(
  59.                 [what](const Message& m) { return m.what == what; });
  60.     }
  61.     void removeAlls() {
  62.         std::unique_lock<std::mutex> lock(_queue_lock);
  63.         if (!_msg_list.empty())
  64.             _msg_list.clear();
  65.         printf("ThreadHandler::removeAlls name: %s",
  66.                                  name.c_str());
  67.     }
  68.     void stop() {
  69.         _stoped = true;
  70.         _cond.notify_all();
  71.         printf("ThreadHandler::stop name: %s", name.c_str());
  72.     }
  73.     void handleMessage(Task&& cb) { _callback = cb; }
  74.    private:
  75.     void dispatchMessage(const Message& msg) const {
  76.         if (msg.task != nullptr) {
  77.             msg.task();
  78.         } else {
  79.             if (msg.what < 0 || _callback == nullptr)
  80.                 return;
  81.             _callback(msg);
  82.         }
  83.     }
  84.     void initLoop() {
  85.         _looper = std::thread([this]() {
  86.             while (true) {
  87.                 Message msg;
  88.                 bool isFired = false;
  89.                 {
  90.                     std::unique_lock<std::mutex> lock(_queue_lock);
  91.                     if (_msg_list.empty()) {
  92.                         _cond.wait(lock, [this] {
  93.                             return _stoped || !_msg_list.empty();
  94.                         });
  95.                     } else {
  96.                         auto front = _msg_list.front();
  97.                         // 如果要when 大于 当前时间,则休眠;否则继续往下执行
  98.                         if (front.when > Clock_t::now()) {
  99.                             if (front.when > Clock_t::now() + maxSleepTime) {
  100.                                 printf(
  101.                                     "ThreadHandler::initLoop time too long name: %s, when: "
  102.                                     "%s ,now: %s , maxSleepTime: %s",
  103.                                     name.c_str(),
  104.                                     std::to_string(
  105.                                         std::chrono::duration_cast<
  106.                                             std::chrono::seconds>(
  107.                                             front.when.time_since_epoch())
  108.                                             .count())
  109.                                         .c_str(),
  110.                                     std::to_string(
  111.                                         std::chrono::duration_cast<
  112.                                             std::chrono::seconds>(
  113.                                             Clock_t::now().time_since_epoch())
  114.                                             .count())
  115.                                         .c_str(),
  116.                                     std::to_string(
  117.                                         std::chrono::duration_cast<
  118.                                             std::chrono::seconds>(maxSleepTime)
  119.                                             .count())
  120.                                         .c_str());
  121.                             }
  122.                             _cond.wait_until(lock, front.when, [this] {
  123.                                 return _stoped || (!_msg_list.empty() &&
  124.                                                    _msg_list.front().when <= Clock_t::now());
  125.                             });
  126.                         }
  127.                     }
  128.                     if (!_stoped && _msg_list.empty())
  129.                         continue;
  130.                     if (_stoped) {
  131.                         _msg_list.clear();
  132.                         return;
  133.                     }
  134.                     // List的头结点的时间小于等于当前时间,则执行头结点任务
  135.                     if (_msg_list.front().when <= Clock_t::now()) {
  136.                         msg = std::move(_msg_list.front());
  137.                         _msg_list.pop_front();
  138.                         isFired = true;
  139.                     }
  140.                 }
  141.                 if (isFired) {
  142.                     dispatchMessage(msg);
  143.                 }
  144.             }
  145.         });
  146.     }
  147.     bool _stoped;
  148.     std::string name;
  149.     std::list<Message> _msg_list;
  150.     std::mutex _queue_lock;
  151.     std::condition_variable _cond;
  152.     std::thread _looper;
  153.     Task _callback;
  154.     std::chrono::minutes maxSleepTime{4};
  155. };
  156. #endif  // _CPP_THREADHANDLER_H
复制代码
Message实现类:
  1. #ifndef _CPP_MESSAGE_H
  2. #define _CPP_MESSAGE_H
  3. #include <chrono>
  4. #include <condition_variable>
  5. #include <functional>
  6. #include <iostream>
  7. #include <list>
  8. #include <map>
  9. #include <memory>
  10. #include <mutex>
  11. #include <thread>
  12. class Message {
  13.    public:
  14.     using TimePoint_t = std::chrono::steady_clock::time_point;
  15.     using Clock_t = std::chrono::steady_clock;
  16.     using MillisDuration_t = std::chrono::milliseconds;
  17.     int what;
  18.     int m_arg1;
  19.     int m_arg2;
  20.     std::function<void()> task;
  21.     TimePoint_t when;
  22.     Message() : Message(-1, 0) {}
  23.     Message(int what) : Message(what, 0) {}
  24.     Message(int what, long delayMillis)
  25.         : what(what), when(Clock_t::now() + MillisDuration_t(delayMillis)) {
  26.         task = nullptr;
  27.     }
  28.     Message(const Message& msg)
  29.         : what(msg.what), task(msg.task), when(msg.when) {}
  30.     Message(Message&& msg) : what(msg.what), task(msg.task), when(msg.when) {}
  31.     ~Message() {}
  32.     Message& operator=(const Message& msg) {
  33.         this->what = msg.what;
  34.         this->when = msg.when;
  35.         this->task = msg.task;
  36.         return *this;
  37.     }
  38.     Message& operator=(Message&& msg) {
  39.         this->what = msg.what;
  40.         this->when = msg.when;
  41.         this->task = std::move(msg.task);
  42.         return *this;
  43.     }
  44.     void setWhen(long delayMillis) {
  45.         when = Clock_t::now() + MillisDuration_t(delayMillis);
  46.     }
  47.     void onRun(std::function<void()>&& f) { this->task = f; }
  48.     bool operator>(const Message& msg) const { return (this->when > msg.when); }
  49.     bool operator<(const Message& msg) const { return (this->when < msg.when); }
  50.     bool operator==(const Message& msg) const {
  51.         return (this->what == msg.what) && (this->task != nullptr) &&
  52.                (msg.task != nullptr);
  53.     }
  54.     bool operator==(int what) const { return (this->what == what); }
  55. };
  56. #endif  // _CPP_MESSAGE_H
复制代码
使用方法:
//构造函数或类初始化中设置如下
mHandler.setName("classATh");
mHandler.handleMessage([&](const Message& msg) { handleMessage(msg); });

void classATh::handleMessage(const Message& msg) {
    if (msg.what == MSG_CODE_QUERY_DEVICE_INFO) {
        //
    } else if (msg.what == MSG_CODE_TRADE_INIT) {
      //
    } else if (msg.what == MSG_CODE_DEVICE_HEART_BEAT) {
        heartBeat();
    }
}
void classATh::startHearBeat() {
    mHandler.removeMessages(MSG_CODE_DEVICE_HEART_BEAT);
    mHandler.sendEmptyMessageDelay(MSG_CODE_DEVICE_HEART_BEAT, 60 * 1000);
}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表