C++11中條件標(biāo)量和互斥鎖應(yīng)用出現(xiàn)死鎖問題
條件變量和互斥鎖在多線程同步過程中經(jīng)常被使用,以下測試程序測試其使用。
1.測試程序1
#include <mutex>
#include <deque>
#include <iostream>
#include <thread>
#include <condition_variable>
class MCTest {
public:
MCTest() : m_work(true), m_max_num(30), m_next_index(0) {
}
void producer_thread() {
while (m_work) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::unique_lock<std::mutex> lk(m_cvMutex);
m_cv.wait(lk);
m_data.push_back(m_next_index++);
std::cout << "producer " << m_next_index << ", queue size: " << m_data.size() << std::endl;
m_cv.notify_all();
}
}
void consumer_thread() {
while (m_work) {
std::unique_lock<std::mutex> lk(m_cvMutex);
m_cv.wait(lk);
int data = m_data.front();
m_data.pop_front();
std::cout << "consumer " << data << ", deque size: " << m_data.size() << std::endl;
m_cv.notify_all();
}
}
private:
bool m_work;
std::mutex m_cvMutex;
std::condition_variable m_cv;
std::deque<int> m_data;
size_t m_max_num;
int m_next_index;
};
int main() {
MCTest obj;
std::thread tp = std::thread(&MCTest::producer_thread, &obj);
std::thread tc = std::thread(&MCTest::consumer_thread, &obj);
tp.join();
tc.join();
return 0;
}運(yùn)行結(jié)果:

2.測試程序2
#include <mutex>
#include <deque>
#include <iostream>
#include <thread>
#include <condition_variable>
class MCTest {
public:
MCTest() : m_work(true), m_max_num(30), m_next_index(0) {
}
void producer_thread() {
while (m_work) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
std::unique_lock<std::mutex> lk(m_cvMutex);
m_cv.wait(lk, [this]() -> bool { return this->m_data.size() < this->m_max_num; });
m_data.push_back(m_next_index++);
std::cout << "producer " << m_next_index << ", queue size: " << m_data.size() << std::endl;
m_cv.notify_all();
}
}
void consumer_thread() {
while (m_work) {
std::unique_lock<std::mutex> lk(m_cvMutex);
m_cv.wait(lk, [this] { return !this->m_data.empty(); });
int data = m_data.front();
m_data.pop_front();
std::cout << "consumer " << data << ", deque size: " << m_data.size() << std::endl;
m_cv.notify_all();
}
}
private:
bool m_work;
std::mutex m_cvMutex;
std::condition_variable m_cv;
std::deque<int> m_data;
size_t m_max_num;
int m_next_index;
};
int main() {
MCTest obj;
std::thread tp = std::thread(&MCTest::producer_thread, &obj);
std::thread tc = std::thread(&MCTest::consumer_thread, &obj);
tp.join();
tc.join();
return 0;
}運(yùn)行結(jié)果:

3.運(yùn)行結(jié)果思考
為什么測試1程序沒有任何輸出,出現(xiàn)死鎖,而程序2正常交替執(zhí)行?
程序1條件變量在得到通知之前會(huì)一直wait,如果線程1獲取了鎖后,阻塞于wait調(diào)用,釋放了互斥鎖,等待通知。此時(shí)線程2執(zhí)行,線程2獲取鎖后,阻塞于阻塞于wait調(diào)用,并釋放互斥鎖,等待喚醒。本質(zhì)上是處于死鎖狀態(tài)。
程序2條件變量處于wait阻塞時(shí),除了得到通知會(huì)解除阻塞外,第二個(gè)參數(shù)為true時(shí),wait函數(shù)也會(huì)返回,所以避免了死鎖的存在。
總結(jié)一下,wait函數(shù)參數(shù)2含義如下:
(1)如果參數(shù)為true,即使沒有收到通知,wait也會(huì)返回,此時(shí)本線程互斥量已經(jīng)加鎖
(2)如果參數(shù)為false,在沒有收到通知時(shí),解鎖互斥量wait一直阻塞
(3)如果沒有參數(shù),與false一樣
到此這篇關(guān)于C++11中條件標(biāo)量和互斥鎖應(yīng)用出現(xiàn)死鎖思考的文章就介紹到這了,更多相關(guān)C++11條件標(biāo)量和互斥鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++ 遍歷目錄下文件簡單實(shí)現(xiàn)實(shí)例
這篇文章主要介紹了c++ 遍歷文件的相關(guān)資料,這里附有實(shí)現(xiàn)實(shí)例代碼,需要的朋友可以參考下2017-02-02
C++實(shí)現(xiàn)將一個(gè)字符串中的字符替換成另一個(gè)字符串的方法
這篇文章主要介紹了C++實(shí)現(xiàn)將一個(gè)字符串中的字符替換成另一個(gè)字符串的方法,需要考慮的情況比較全面,有不錯(cuò)的借鑒價(jià)值,需要的朋友可以參考下2014-09-09
基于matlab MFCC+GMM的安全事件聲學(xué)檢測系統(tǒng)
這篇文章主要為大家介紹了基于matlab MFCC+GMM的安全事件聲學(xué)檢測系統(tǒng)實(shí)現(xiàn)及源碼示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-02-02
Qt音視頻開發(fā)之通用監(jiān)控布局控件的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了如何利用Qt開發(fā)一個(gè)通用的監(jiān)控布局控件,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Qt開發(fā)有一定的幫助,需要的可以參考一下2023-01-01
C語言 以數(shù)據(jù)塊的形式讀寫文件詳解及實(shí)現(xiàn)代碼
本文主要介紹 C語言 以數(shù)據(jù)塊的形式讀寫文件,這里對相關(guān)知識資料做了整理,并附代碼示例,以便大家學(xué)習(xí)參考,有學(xué)習(xí)此部分知識的朋友可以參考下2016-08-08
C++如何調(diào)用opencv完成運(yùn)動(dòng)目標(biāo)捕捉詳解
OpenCV作為機(jī)器視覺開源庫,使用起來非常不錯(cuò),這篇文章主要給大家介紹了關(guān)于C++如何調(diào)用opencv完成運(yùn)動(dòng)目標(biāo)捕捉的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05

