c++ - 在 C++11 中实现看门狗定时器

标签 c++ c++11 timer watchdog

我正在尝试在 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/

相关文章:

c++ - 有没有一种通用的方法可以用 SFINAE 否定 decltype 条件?

c++11 - 使用 boost odeint 进行精确的多维积分

java - 使用具有不同预期间隔的计时器执行周期性任务

javascript - Angular 8 中 60 秒过去后如何将秒转换为分钟?

c++ - 如何使用用户定义的键控制和修改 std::map 排序

c++ - protobuf 必填字段和默认值

c++ - 为搜索优化 C++ vector

c++ - 如何在 C++11 中初始化(通过初始化列表)多维 std::array?

c++ - Editreturn 我不太明白这里问的递归函数的概念 (c++)

objective-c - cocoa 中的计时器?