马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
在java开发中,风俗使用Handler、Message来处置惩罚同步,比如对相机的利用(open、setParamters、start、stop、clost)全部抛到同一个线程处置惩罚,防止并发利用导致非常,如许保存给外部的同一接口就是安全的,无论外部哪些线程来调用,终极到控制模块都是在同一线程处置惩罚相机利用。这里提供一个C++实现的Handler Message封装,可以实现类似安卓那样的接口;
Handler类封装:- #ifndef _CPP_THREADHANDLER_H
- #define _CPP_THREADHANDLER_H
- #include <algorithm>
- #include <chrono>
- #include <condition_variable>
- #include <functional>
- #include <iostream>
- #include <list>
- #include <map>
- #include <memory>
- #include <mutex>
- #include <thread>
- #include "Message.h"
- class ThreadHandler {
- public:
- using TimePoint_t = std::chrono::steady_clock::time_point;
- using Clock_t = std::chrono::steady_clock;
- using MillisDuration_t = std::chrono::milliseconds;
- using Task = std::function<void(const Message& msg)>;
- ThreadHandler() : _stoped(false) { initLoop(); }
- ~ThreadHandler() {
- _stoped = true;
- _cond.notify_all();
- _looper.join();
- }
- void setName(const std::string n) { this->name = n; }
- bool sendEmptyMessageDelay(int what, long delay_millis) {
- if (what < 0 || delay_millis < 0)
- return false;
- Message msg(what, delay_millis);
- std::unique_lock<std::mutex> lock(_queue_lock);
- _msg_list.push_back(msg);
- _msg_list.sort(std::less<Message>());
- _cond.notify_all();
- return true;
- }
- bool sendEmptyMessageDelay(int what) {
- return sendEmptyMessageDelay(what, 0);
- }
- bool postDelay(std::function<void()>&& f, long delay_millis) {
- if (f == nullptr || delay_millis < 0) {
- return false;
- }
- std::unique_lock<std::mutex> lock(_queue_lock);
- Message msg(0, delay_millis);
- msg.onRun(std::move(f));
- _msg_list.push_back(msg);
- _msg_list.sort(std::less<Message>());
- _cond.notify_all();
- return true;
- }
- bool post(std::function<void()>&& f) { return postDelay(std::move(f), 0); }
- void removeMessages(int what) {
- if (what < 0)
- return;
- std::unique_lock<std::mutex> lock(_queue_lock);
- if (!_msg_list.empty())
- _msg_list.remove_if(
- [what](const Message& m) { return m.what == what; });
- }
- void removeAlls() {
- std::unique_lock<std::mutex> lock(_queue_lock);
- if (!_msg_list.empty())
- _msg_list.clear();
- printf("ThreadHandler::removeAlls name: %s",
- name.c_str());
- }
- void stop() {
- _stoped = true;
- _cond.notify_all();
- printf("ThreadHandler::stop name: %s", name.c_str());
- }
- void handleMessage(Task&& cb) { _callback = cb; }
- private:
- void dispatchMessage(const Message& msg) const {
- if (msg.task != nullptr) {
- msg.task();
- } else {
- if (msg.what < 0 || _callback == nullptr)
- return;
- _callback(msg);
- }
- }
- void initLoop() {
- _looper = std::thread([this]() {
- while (true) {
- Message msg;
- bool isFired = false;
- {
- std::unique_lock<std::mutex> lock(_queue_lock);
- if (_msg_list.empty()) {
- _cond.wait(lock, [this] {
- return _stoped || !_msg_list.empty();
- });
- } else {
- auto front = _msg_list.front();
- // 如果要when 大于 当前时间,则休眠;否则继续往下执行
- if (front.when > Clock_t::now()) {
- if (front.when > Clock_t::now() + maxSleepTime) {
- printf(
- "ThreadHandler::initLoop time too long name: %s, when: "
- "%s ,now: %s , maxSleepTime: %s",
- name.c_str(),
- std::to_string(
- std::chrono::duration_cast<
- std::chrono::seconds>(
- front.when.time_since_epoch())
- .count())
- .c_str(),
- std::to_string(
- std::chrono::duration_cast<
- std::chrono::seconds>(
- Clock_t::now().time_since_epoch())
- .count())
- .c_str(),
- std::to_string(
- std::chrono::duration_cast<
- std::chrono::seconds>(maxSleepTime)
- .count())
- .c_str());
- }
- _cond.wait_until(lock, front.when, [this] {
- return _stoped || (!_msg_list.empty() &&
- _msg_list.front().when <= Clock_t::now());
- });
- }
- }
- if (!_stoped && _msg_list.empty())
- continue;
- if (_stoped) {
- _msg_list.clear();
- return;
- }
- // List的头结点的时间小于等于当前时间,则执行头结点任务
- if (_msg_list.front().when <= Clock_t::now()) {
- msg = std::move(_msg_list.front());
- _msg_list.pop_front();
- isFired = true;
- }
- }
- if (isFired) {
- dispatchMessage(msg);
- }
- }
- });
- }
- bool _stoped;
- std::string name;
- std::list<Message> _msg_list;
- std::mutex _queue_lock;
- std::condition_variable _cond;
- std::thread _looper;
- Task _callback;
- std::chrono::minutes maxSleepTime{4};
- };
- #endif // _CPP_THREADHANDLER_H
复制代码 Message实现类:- #ifndef _CPP_MESSAGE_H
- #define _CPP_MESSAGE_H
- #include <chrono>
- #include <condition_variable>
- #include <functional>
- #include <iostream>
- #include <list>
- #include <map>
- #include <memory>
- #include <mutex>
- #include <thread>
- class Message {
- public:
- using TimePoint_t = std::chrono::steady_clock::time_point;
- using Clock_t = std::chrono::steady_clock;
- using MillisDuration_t = std::chrono::milliseconds;
- int what;
- int m_arg1;
- int m_arg2;
- std::function<void()> task;
- TimePoint_t when;
- Message() : Message(-1, 0) {}
- Message(int what) : Message(what, 0) {}
- Message(int what, long delayMillis)
- : what(what), when(Clock_t::now() + MillisDuration_t(delayMillis)) {
- task = nullptr;
- }
- Message(const Message& msg)
- : what(msg.what), task(msg.task), when(msg.when) {}
- Message(Message&& msg) : what(msg.what), task(msg.task), when(msg.when) {}
- ~Message() {}
- Message& operator=(const Message& msg) {
- this->what = msg.what;
- this->when = msg.when;
- this->task = msg.task;
- return *this;
- }
- Message& operator=(Message&& msg) {
- this->what = msg.what;
- this->when = msg.when;
- this->task = std::move(msg.task);
- return *this;
- }
- void setWhen(long delayMillis) {
- when = Clock_t::now() + MillisDuration_t(delayMillis);
- }
- void onRun(std::function<void()>&& f) { this->task = f; }
- bool operator>(const Message& msg) const { return (this->when > msg.when); }
- bool operator<(const Message& msg) const { return (this->when < msg.when); }
- bool operator==(const Message& msg) const {
- return (this->what == msg.what) && (this->task != nullptr) &&
- (msg.task != nullptr);
- }
- bool operator==(int what) const { return (this->what == what); }
- };
- #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企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金 |