1. 程式人生 > 其它 >安全退出_如何在類的內部建立執行緒並安全退出

安全退出_如何在類的內部建立執行緒並安全退出

技術標籤:安全退出

應用場景:有個控制感測器的類,在這個類開始的時候需要建立一個執行緒,用來監控這些感測器是否線上。這時候就可以在類開始的時候,建立一個執行緒監控感測器的狀態。

關於監控執行緒需要注意兩個問題:
1、執行緒建立之後,很多人的寫法是直接一個while死迴圈讓程式空轉,這樣效率低並且浪費資源;
2、當類析構的時候,一定要讓執行緒正常退出。

ExitThread.h


#pragma once
#include
#include
#include
#include
#include
using namespace std; class CExitThread
{ public:
CExitThread();
~CExitThread(); //執行緒函式
void t_Start(); //通知執行緒執行
void Notify(); private:
std::mutex m_Mutex_;
std::condition_variable m_Var_; bool m_bReady_ = false; bool m_bExit_ = false;
std::future<void> m_fuThread_;
};

C++11寫法中,上述類的private成員基本上是配套的變數,這些變數都會線上程中用上。

ExitThread.cpp

程式碼解釋看註釋。


#include "ExitThread.h"

CExitThread::CExitThread()
{
std::cout << "呼叫建構函式,同時建立執行緒.\n";
m_fuThread_ = std::async(std::launch::async, &CExitThread::t_Start, this);
}
CExitThread::~CExitThread()
{
{
std::unique_lock<:mutex> locker(m_Mutex_);
m_bReady_ = true;
}
m_Var_.notify_one();
m_bExit_ = true;
m_fuThread_.get();
std::cout << "呼叫解構函式.\n";
} void CExitThread::Notify()
{ //通知執行緒進行操作//這步類似於windows自帶API WaitForSingleObject();
{
std::unique_lock<:mutex> locker(m_Mutex_);
m_bReady_ = true;
}
m_Var_.notify_one();
} void CExitThread::t_Start()
{ while (true)
{
{
std::unique_lock<:mutex> locker(m_Mutex_); while (!m_bReady_) m_Var_.wait(locker);
} //執行緒被通知之後,就會進入到while迴圈,一直迴圈//以下兩句程式碼測試用....
Sleep(1000);
std::cout << "...get notify.\n"; //當該執行緒再次被通知,且m_bExit_為true時,才退出這個while迴圈//if (m_bExit_) break;
}
std::cout << "Exit Thread.\n";
}

main.cpp測試程式碼

    #include 
#include
#include "ExitThread.h"
#include
using namespace std; int main()
{ //呼叫類的建構函式,建立內部執行緒
std::shared_ptr pSensor = std::make_shared(); //通知類內部的執行緒,進入到執行緒中的whlie迴圈//
pSensor->Notify();
Sleep(6000);
std::cout << "main::Hello World.\n"; return 0;
}

執行結果如下圖所示:

3abf99219123a87421ffe6dce64810aa.png


當呼叫Notify的時候,進入到執行緒內部,迴圈列印“…process”。
pSensor跳出main函式作用域呼叫解構函式,退出執行緒。

在解構函式中,需要呼叫m_fuThread.get();等待執行緒執行完畢。

公眾號程式碼預覽效果實在不行,移步CSDN:

https://blog.csdn.net/WOODS_CTBU/article/details/107180868