我正在尝试在 C++ 11 中实现一个小的看门狗定时器类,它应该在到期时调用一些代码。
看门狗.h:
#pragma once
#include <thread>
#include <atomic>
class Watchdog
{
public:
Watchdog();
Watchdog(unsigned int milliseconds, std::function<void()> callback);
~Watchdog();
void Start(unsigned int milliseconds, std::function<void()> callback);
void Stop();
void Pet();
private:
unsigned int _interval;
std::atomic<unsigned int> _timer;
std::atomic<bool> _running;
std::thread _thread;
std::function<void()> _callback;
void Loop();
};
看门狗.cpp:
#include "Watchdog.h"
Watchdog::Watchdog() :
_interval(0),
_timer(0),
_running(false)
{
}
Watchdog::Watchdog(unsigned int milliseconds, std::function<void()> callback)
{
Start(milliseconds, callback);
}
Watchdog::~Watchdog()
{
}
void Watchdog::Start(unsigned int milliseconds, std::function<void()> callback)
{
_interval = milliseconds;
_timer = 0;
_callback = callback;
_running = true;
_thread = std::thread(&Watchdog::Loop, this);
}
void Watchdog::Stop()
{
_running = false;
_thread.join();
}
void Watchdog::Pet()
{
_timer = 0;
}
void Watchdog::Loop()
{
while (_running)
{
_timer++;
if (_timer >= _interval)
{
_running = false;
_callback();
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
但是,这个线程循环对我来说似乎有点脏,而且 std::this_thread::sleep_for
不准确(它休眠了至少指定的时间,这意味着它可以超过 1 毫秒),是否有更好的方法来实现此功能?
最佳答案
看起来很有趣,我可以想出这段代码。 它无法编译,您必须为此做很多工作,但它展示了一个关于如何编译的想法。
std::mutex cmutex; // needed for the condition_variable
std::condition_variable stop_condition;
std::chrono::time_point last_pet_time;
void Watchdog::Start(unsigned int milliseconds, std::function<void()> callback)
{
// somewhere in this method:
last_pet_time = now();
timeout = milliseconds;
}
void Watchdog::Stop()
{
if (_running) {
std::unique_lock<std::mutex> lock(cmutex);
_running = false;
stop_condition.notify_all(); // tell Loop() to stop
_thread.join();
}
}
void Watchdog::Pet()
{
std::unique_lock<std::mutex> lock(cmutex);
last_pet_time = now();
}
void Watchdog::Loop()
{
std::unique_lock<std::mutex> lock(cmutex);
while (_running // was Stop() called?
and (now() - last_pet_time) < timeout) // was Pet() ( or Start() ) called recently?
{
// here the threads waits until:
// 1. the condition_variable is notified in ::Stop()
// 2. or the timeout expires
// 3. or until spurious wakeup
stop_condition.wait_for(lock, timeout);
}
if (_running) {
_running = false;
callback();
}
}
检查:http://en.cppreference.com/w/cpp/thread/condition_variable/wait_until
关于c++ - 在 C++11 中实现看门狗定时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35824878/