2017-03-11 30 views
1

オンラインC++11コンパイラを使用しています。リンクはcpp.sh(C++シェル)です。C++ 11 Watchdogクラス、テストアプリケーションを終了したくない

私の現在のプロジェクトでは、スレッドや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 
    } 
} 

いくつかの追加提案:trueまたはfalseと比較しない、シンプルなif条件を使用しています。

+0

_Question_:「真偽」との比較を避けるべき理由は何ですか?事前に感謝:) –

+0

@グロネン単に読みにくいので。 )いくつかの文字を保存します;) –

+0

これは、 '' m_mutex'' **を** 'join()'の前にロック解除することです。 –

関連する問題