使用互斥元保护共享数据-lock_guard
用互斥元保護(hù)共享數(shù)據(jù)
線程相對(duì)于進(jìn)程的優(yōu)勢(shì)在于能夠共享數(shù)據(jù),線程相對(duì)于進(jìn)程的劣勢(shì)也在于數(shù)據(jù)能夠共享。如何多個(gè)線程安全的訪問數(shù)據(jù),你可以使用互斥鎖保護(hù)數(shù)據(jù),也可以優(yōu)化數(shù)據(jù)結(jié)構(gòu)使用無鎖編程,或者使用事務(wù)保證數(shù)據(jù)同一時(shí)間只能被一個(gè)線程訪問。
這里主要說的就是如何使用互斥鎖對(duì)數(shù)據(jù)進(jìn)行保護(hù),使用互斥鎖有一個(gè)問題就是需要使用者,在需要更改數(shù)據(jù)的時(shí)候調(diào)用lock()對(duì)數(shù)據(jù)加鎖,在更改數(shù)據(jù)結(jié)束之后調(diào)用unlock()對(duì)數(shù)據(jù)解鎖,如果漏掉解鎖或者因?yàn)楫惓L幚碓蛱^解鎖函數(shù)會(huì)導(dǎo)致死鎖。
人為的去加鎖和解鎖不可避免的會(huì)出現(xiàn)只寫了加鎖而忘記解鎖的情況,但是C++有一類函數(shù)會(huì)自動(dòng)的執(zhí)行,這些函數(shù)就是類的構(gòu)造函數(shù)和類的析構(gòu)函數(shù),當(dāng)創(chuàng)建類的時(shí)候自動(dòng)的調(diào)用構(gòu)造函數(shù),當(dāng)類銷毀的時(shí)候就會(huì)調(diào)用析構(gòu)函數(shù),不需要人為的參與,這樣就避免了因?yàn)槿藶榈脑驅(qū)е碌乃梨i問題,C++已經(jīng)提供了該類的實(shí)現(xiàn),就是接下來要介紹的lock_guard函數(shù)
為了防止出現(xiàn)這種狀況可以使用類的構(gòu)造和析構(gòu)進(jìn)行數(shù)據(jù)的加鎖和解鎖
具體實(shí)現(xiàn)如下:
template<typename _Mutex> class lock_guard {public:typedef _Mutex mutex_type;// 調(diào)用構(gòu)造函數(shù) 進(jìn)行加鎖explicit lock_guard(mutex_type& __m) : _M_device(__m){ _M_device.lock(); }lock_guard(mutex_type& __m, adopt_lock_t) noexcept : _M_device(__m){ } // calling thread owns mutex// 調(diào)用析構(gòu)函數(shù)進(jìn)行解鎖~lock_guard(){ _M_device.unlock(); }lock_guard(const lock_guard&) = delete;lock_guard& operator=(const lock_guard&) = delete;private:mutex_type& _M_device; };設(shè)計(jì)一個(gè)利用lock_guard進(jìn)行加鎖和解鎖的demo如下:
// // Created by andrew on 2021/3/31. // #include <iostream> #include <list> #include <mutex> #include <algorithm>using namespace std;// 聲明一個(gè)卻局鏈表 list<int> g_list; // 聲明一個(gè)互斥鎖用于保護(hù)全局鏈表數(shù)據(jù) mutex list_mutex;void push_data_to_list(int newValue) { // 每次進(jìn)來創(chuàng)建guard, 構(gòu)造函數(shù)中會(huì)調(diào)用全局鎖,在該函數(shù)退出的時(shí)候會(huì)自動(dòng)調(diào)用析構(gòu)函數(shù)實(shí)現(xiàn) // 鎖的釋放lock_guard<std::mutex> guard(list_mutex);g_list.push_back(newValue); }bool find_list_data(int valueData) {lock_guard<mutex> guard(list_mutex);return find(g_list.begin(), g_list.end(), valueData) != g_list.end(); }int main(int argc, char * argv[]) {push_data_to_list(42);cout << "find 1 = " << find_list_data(1) << " find 42 = " << find_list_data(42) << endl;return 0; }總結(jié)
以上是生活随笔為你收集整理的使用互斥元保护共享数据-lock_guard的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 作者:熊刚,男,博士,现任中国科学院自动
- 下一篇: 原子操作和互斥量的区别