C++實現(xiàn)一個簡易版的事件(Event)的示例代碼
一、前言
利用 WaitForSingleObject 檢查內(nèi)核對象的狀態(tài)來進行實現(xiàn)。后來隨著需要開發(fā)跨平臺的程序后這種方式就不能使用了, 畢竟這是 windows 專屬。 POCO 庫在 windows之外的系統(tǒng)選擇利用 pthread 線程庫庫來實現(xiàn) Event, pthread 畢竟不在C++標(biāo)準(zhǔn)庫里面,假設(shè)要使用的話需要單獨配置。所以本文就利用 C++11之后的標(biāo)準(zhǔn)庫內(nèi)容來實現(xiàn)一個事件類, 方便使用。
本文代碼地址:https://github.com/pengguoqing/samples_code
二、實現(xiàn)
2.1 需要具備的功能
①支持多線程
②可以等待一定時間
2.2 代碼實現(xiàn)
一共提供四個對外接口, 分別如下:
//設(shè)置事件有信號
inline void SetEvent() const;
//重置事件為無信號
inline void ResetEvent() const;
//持續(xù)等待直到事件有信號, 如果是 Auto 模式則必須等待到該線程能拿到狀態(tài)
inline void Wait() const;
//等待事件一定時間, 時間范圍內(nèi)事件有信號則返回 true,否則返回 false
template <typename Rep, typename Period>
inline bool tryWait(const std::chrono::duration<Rep, Period>& duratio) const;
類內(nèi)部再對具體的實現(xiàn)進行一下封裝
struct EventImpl
{
explicit EventImpl(Mode mode, bool initState);
~EventImpl() = default;
inline void Set();
inline void Reset();
inline void Wait();
template <typename Rep, typename Period>
inline bool Wait_for(const std::chrono::duration<Rep, Period>& duration);
std::mutex m_mutex;
std::condition_variable m_condi;
bool m_signal;
const Mode m_mode;
};
使用 unique_ptr 對 EventImpl 資源進行管理:
const std::shared_ptr<EventImpl> m_event;
因為沒有裸露的指針資源,移動和拷貝函數(shù)就直接全部使用編譯器默認的
explicit CXEvent(Mode mode = Mode::Auto, bool initstate = false); ~CXEvent() = default;
三、測試
測試用一個事件實例來實現(xiàn)兩個線程的同步測試, 鍵盤輸入字符 ‘s’ 觸發(fā)一次事件, 每個線程 Wait() 兩次事件后,再測試一下 tryWait() 時間。代碼如下:
using namespace std;
static CXEvent kEvent;
static constexpr int testCnt = 3;
TestEventFunc1(const CXEvent& refEvent)
{
for (int i=0; i< testCnt; i++)
{
if (i == testCnt-1)
{
auto begin = chrono::high_resolution_clock::now();
kEvent.tryWait(5000ms);
auto end = chrono::high_resolution_clock::now();
auto duration = chrono::duration_cast<chrono::microseconds>(end - begin);
cout << "TestEventFunc1"<<"tryWait time:"<< duration.count() << endl;
}
else
{
kEvent.Wait();
cout << "TestEventFunc1 Wait" << endl;
}
}
}
TestEventFunc2(const CXEvent& refEvent)
{
for (int i=0; i<testCnt; i++)
{
if (i == testCnt-1)
{
auto begin = chrono::high_resolution_clock::now();
kEvent.tryWait(5000ms);
auto end = chrono::high_resolution_clock::now();
auto duration = chrono::duration_cast<chrono::microseconds>(end - begin);
cout << "TestEventFunc2" << "tryWait time:"<< duration.count()<< endl;
}
else
{
kEvent.Wait();
cout << "TestEventFunc2 Wait" << endl;
}
}
}
int main()
{
CXEvent refEvent1(kEvent);
CXEvent refEvent2(kEvent);
std::thread testTh1(TestEventFunc1, refEvent1);
std::thread testTh2(TestEventFunc2, refEvent2);
int cinCnt{0};
char inputCmd {'R'};
cin.get(inputCmd);
while ('q'!=inputCmd && cinCnt<testCnt*2)
{
if ('s' == inputCmd)
{
kEvent.SetEvent();
cinCnt++;
}
cin.get(inputCmd);
}
if (testTh1.joinable())
{
testTh1.join();
}
if (testTh2.joinable())
{
testTh2.join();
}
std::cout << "test set event and wait_for event\n";
}
期望結(jié)果是每輸入一次 ‘s’ 回車后,TestEventFunc1或者TestEventFunc2線程函數(shù)中的循環(huán)體就會被執(zhí)行一次,每個循環(huán)體執(zhí)行兩次后等待 5 秒線程就退出,再輸入‘q’ 退出程序。實際運行結(jié)果如下:

符合預(yù)期。
到此這篇關(guān)于C++實現(xiàn)一個簡易版的事件(Event)的示例代碼的文章就介紹到這了,更多相關(guān)C++事件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實現(xiàn)的O(n)復(fù)雜度內(nèi)查找第K大數(shù)算法示例
這篇文章主要介紹了C++實現(xiàn)的O(n)復(fù)雜度內(nèi)查找第K大數(shù)算法,結(jié)合實例形式分析了算法的原理以及具體實現(xiàn)方法,需要的朋友可以參考下2017-08-08
C++實現(xiàn)LeetCode(211.添加和查找單詞-數(shù)據(jù)結(jié)構(gòu)設(shè)計)
這篇文章主要介紹了C++實現(xiàn)LeetCode(211.添加和查找單詞-數(shù)據(jù)結(jié)構(gòu)設(shè)計),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08

