2017-03-11 97 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'的右邊**,對嗎? –