2017-03-11 94 views
1

我正在使用在线C++11编译器,链接在这里找到:cpp.sh(C++ Shell)。C++ 11看门狗类,测试应用程序不想退出

在我当前的项目中,我希望有一个看门狗类,以便能够以某种方式检查线程或FSM的状态(例如)。

经过一番工作(我不是C++11古茹),我终于得到了下面的代码,编译好了。
我也做了一些基本的/平凡的测试,但似乎测试程序不想退出
它说:“程序运行”和(力)出口的唯一方法是打出了“停止”按钮... :(

好吧,我问题我在做什么?错误
任何想法,你可以提供建议高度赞赏

这里是full code,包括我的测试应用程序。

看门狗(如MCVE):

#include <thread> 
#include <atomic> 
#include <chrono> 
#include <condition_variable> 
#include <mutex> 
#include <iostream> 

using namespace std::chrono; 

class Watchdog 
{ 
public: 
    Watchdog(); 
    ~Watchdog(); 
    void Start(unsigned int milliseconds, std::function<void()> callback = 0); 
    void Stop(); 
    void Pet(); 

private: 
    unsigned int m_interval; 
    std::atomic<bool> m_running; 
    std::thread m_thread; 
    std::function<void()> m_callback; 
    std::mutex m_mutex; 
    steady_clock::time_point m_lastPetTime; 
    std::condition_variable m_stopCondition; 
    void Loop(); 
}; 

Watchdog::Watchdog() 
{ 
    m_running = false; 
} 

Watchdog::~Watchdog() 
{ 
    Stop(); 
} 

void Watchdog::Start(unsigned int milliseconds, std::function<void()> callback) 
{ 
    std::unique_lock<std::mutex> locker(m_mutex); 
    if(m_running == false) 
    { 
     m_lastPetTime = steady_clock::now(); 
     m_interval = milliseconds; 
     m_callback = callback; 
     m_running = true; 
     m_thread = std::thread(&Watchdog::Loop, this); 
    } 
} 

void Watchdog::Stop() 
{ 
    std::unique_lock<std::mutex> locker(m_mutex); 
    if(m_running == true) 
    { 
     m_running = false; 
     m_stopCondition.notify_all(); 
     m_thread.join(); 
    } 
} 

void Watchdog::Pet() 
{ 
    std::unique_lock<std::mutex> locker(m_mutex); 
    m_lastPetTime = steady_clock::now(); 
    m_stopCondition.notify_all(); 
} 

void Watchdog::Loop() 
{ 
    std::unique_lock<std::mutex> locker(m_mutex); 
    while(m_running == true) 
    { 
     if(m_stopCondition.wait_for(locker, milliseconds(m_interval)) == std::cv_status::timeout) 
     { 
      if(m_callback != nullptr) 
       m_callback(); 
     } 
    } 
} 

int main(int argc, char *argv[]) 
{ 
    Watchdog wdog; 

    wdog.Start(3000, [] { std::cout << " WDOG TRIGGERED!!! "; }); 
    for(auto i = 0; i < 10; i++) 
    { 
     std::cout << "[+]"; 
     wdog.Pet(); 
     std::this_thread::sleep_for(std::chrono::milliseconds(500)); 
    } 
} 

-

回答

2

你在这里做一个僵局。

void Watchdog::Stop() 
{ 
    std::unique_lock<std::mutex> locker(m_mutex); 
    if(m_running == true) 
    { 
     m_running = false; 
     m_stopCondition.notify_all(); 
     m_thread.join(); 
     ^~~~~~~~~~~~~~~ 
      m_mutex is locked; m_thread cannot continue execution 
    } 
} 

一些附加的建议:用简单的if条件,不与truefalse比较。

+0

_Question_:你应该避免与'true/false'比较的原因是什么?在此先感谢:) –

+0

@groenhen只是因为他们很难阅读。它也保存了一些字符;) –

+0

所以,这个想法是在**'join()'之前解开'm_mutex'的右边**,对吗? –