2017-03-11 8 views
1

온라인 C++11 컴파일러를 사용하고 있습니다. 링크는 cpp.sh (C++ 쉘)입니다.C++ 11 Watchdog 클래스, 테스트 응용 프로그램을 종료하지 않으려 고합니다.

현재 프로젝트에서는 워치 독 클래스를 사용하여 어떻게 든 스레드 또는 FSM (예 :)의 상태를 확인할 수 있습니다.

일부 작업 후 (나는 C++11 전문가가 아닙니다), 마침내 아래 코드를 얻었습니다.
나는 또한 기본적인/사소한 테스트를했는데, 테스트 프로그램이 끝내기를 원하지 않는다..
그것은 "프로그램을 실행"라고하고 (강제) 종료 할 수있는 유일한 방법은, :(...은 "정지"버튼을 누르면 내 질문

음이다 내가 뭘 ? 잘못된
모든 아이디어는 당신이 제공 할 수있는 제안을 매우 높이 평가된다 여기

full code입니다, 내 테스트 응용 프로그램을 포함 :.

(MCVE 등) 6,

워치 독 :

#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_ : 'true/false'와 비교해서는 안되는 이유는 무엇입니까? 미리 감사드립니다 :) –

+0

@ groenhen 왜냐하면 그들은 읽기가 어렵 기 때문입니다.) 일부 문안을 저장한다;) –

+0

그래서, ** join()을하기 전에'm_mutex' 권리를 잠금 해제하는 것입니다. –