使用boost模板函數實現讀寫鎖

介紹

  • shared_mutex即讀寫鎖,不同與我們常用的獨占式鎖mutex,shared_mutex是共享與獨占共存的鎖,實現了讀寫鎖的機制,即多個讀線程一個寫線程,通常用于對于一個共享區域的讀操作比較頻繁,而寫操作比較少的情況。
  • 讀寫鎖比起mutex具有更高的適用性,具有更高的并行性,可以有多個線程同時占用讀模式的讀寫鎖,但是只能有一個線程占用寫模式的讀寫鎖,讀寫鎖的基本規則可以總結為“寫優先,讀共享,交叉互斥“,具體表現為讀寫鎖的三種狀態:

? ? ? ? (1)當讀寫鎖是寫加鎖狀態時,在這個鎖被解鎖之前,所有試圖對這個鎖加鎖的線程都會被阻塞。(交叉互斥)
? ? ? ? (2)當讀寫鎖在讀加鎖狀態時,所有試圖以讀模式對它進行加鎖的線程都可以得到訪問權,但是以寫模式對它進行加鎖的線程將會被阻塞。(讀共享,交叉互斥)
? ? ? ? (3)當讀寫鎖在讀模式的鎖狀態時,如果有另外的線程試圖以寫模式加鎖,讀寫鎖通常會阻塞隨后的讀模式鎖的請求,這樣可以避免讀模式鎖長期占用,而等待的寫模式鎖請求則長期阻塞。(寫優先)

  • 注:其實在讀者-寫者問題中,有讀者優先和寫者優先兩種模式,只是在boost中的shared_mutex默認的實現是寫者優先,這其實也是有道理的,因為在我們總是希望讀到的數據是最新的,這就得保證寫者優先。
  • 下面通過一個 boost::shared_mutex的應用實例來反應其鎖機制,該例子中我們建立多個讀者線程,兩個寫者線程,程序的實際運行結果很直接的反應了shared_mutex應用情況。

代碼

#include <boost/thread/thread.hpp>
#include <boost/ref.hpp>
#include <string>boost::shared_mutex global_mutex;
int global_num = 10;//全局變量,寫者改變全局變量,讀者讀全局變量//讀線程
void read_thread(std::string &name){boost::shared_lock<boost::shared_mutex> lock(global_mutex);//讀鎖定 shared_lockprintf("線程%s搶占了資源,global_num = %d\n",name.c_str(),global_num);boost::this_thread::sleep(boost::posix_time::seconds(1));printf("線程%s釋放了資源...\n",name.c_str());
}//寫線程
void write_thread(std::string &name){boost::unique_lock<boost::shared_mutex> lock(global_mutex);//寫鎖定 unique_lockglobal_num++;//寫線程改變數據的數值printf("線程%s搶占了資源,global_num = %d\n",name.c_str(),global_num);boost::this_thread::sleep(boost::posix_time::seconds(1));printf("線程%s釋放了資源...\n",name.c_str());}
int main(){std::string read_thread_r1 = "read_thread_r1";std::string read_thread_r2 = "read_thread_r2";std::string read_thread_r3 = "read_thread_r3";std::string read_thread_r4 = "read_thread_r4";std::string read_thread_r5 = "read_thread_r5";std::string write_thread_w1 = "write_thread_w1";std::string write_thread_w2 = "write_thread_w2";boost::thread_group tg;tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r1)));tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r2)));tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r3)));tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r4)));tg.create_thread(boost::bind(read_thread,boost::ref(read_thread_r5)));tg.create_thread(boost::bind(write_thread,boost::ref(write_thread_w1)));tg.create_thread(boost::bind(write_thread,boost::ref(write_thread_w2)));tg.join_all();return 0;
}

程序運行結果

結論

  • 從運行結果中可以看出,如果是讀者獲得了shared_mutex,則其他讀者可以同時搶占資源,但如果是寫者獲得了shared_mutex,則其他的寫者或讀者都不能進入臨界區,即同時只有一個寫者能進入臨界區。?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446836.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446836.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446836.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

安卓內邊距padding與外邊距magrin

內邊距padding與外邊距margin 內邊距只有容器才有,即里面要有視圖 具體示例

Android Studio發布項目到jcenter

目錄一、創建Bintray賬戶及Maven倉庫二、上傳項目到jcenter1、配置Android項目2、Gradle命令上傳3、在項目中引用4、Add to JCenter三、Demo示例一、創建Bintray賬戶及Maven倉庫 1、打開Bintray首頁&#xff0c;點擊 For an Open Source Account &#xff0c;快速注冊或者用第…

C++讀取文件,將文件內容讀到string字符串里面

使用stringstream和ifstream實現 代碼 std::ifstream f{file_name, std::ios::binary};std::stringstream ss;ss << f.rdbuf();auto data ss.str();

Android MotionEvent中getX()、getRawX()和getTop()的區別

為了展示getX()、getRawX()和getTop()方法的區別&#xff0c;我們寫了一個簡單的測試Demo&#xff0c;我們寫了一個自定義控件&#xff08;繼承ImageView&#xff09;。 package com.demo.ui;import android.content.Context; import android.support.annotation.Nullable; im…

C++常量

常量 1.字面常量與符號常量 字面常量:從字面形式可以識別的常量 eg:1.2;‘A’ 整型常量:八進制(以0開頭),十六進制(以0x或0X開頭) 浮點型常量: 小數形式(整數和小數可以省略其中之一------為0時) eg:.123(0.123) 123.(123.0) 指數形式 0.23e1(0.2310^1) 0.23E-2(0.2310^-2)…

Synchronization 進程鎖

Boost.Interprocess允許多個進程同時使用共享內存。因為共享內存從定義上來說是進程間共享的&#xff0c;所以Boost.Interprocess需要支持某種同步。想到同步&#xff0c;我們會想到C11標準庫中的類或Boost.Thread。但是這些類只能用來同步同一進程內的線程&#xff0c;它們不支…

Android 獲取屏幕寬度和高度的幾種方法

方法一&#xff1a; public static void getScreenSize1(Context context){WindowManager windowManager (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);Display defaultDisplay windowManager.getDefaultDisplay();Point point new Point();defaultD…

毛概 第二章新民主主義革命理論

1.新民主主義革命的總路線 2.

解決undefined reference to symbol ‘sem_close@@GLIBC_2.2.5‘問題

錯誤圖示 問題原因 編譯的時候&#xff0c;沒有引入庫文件 sem()位于pthread庫中&#xff0c;所以在編譯和鏈接時請確保使用-pthread標志&#xff0c;因此在編譯的時候需要導入pthread庫文件編譯的順序出現問題 解決辦法 在clion的CMakeLists.txt文件中添加這一行代碼set(CM…

Android 在onCreate()方法中獲取控件寬高值為0解決方案

大家很多時候需要在Activity或者Fragment的onCreate()方法中獲取聲明的空間的高度或者寬度&#xff0c;進行位置移動或者其他操作&#xff0c;但是當調用 view.getHeight() 或者 view.getWidth() 獲取的竟然為0。。。 其實很容易理解&#xff0c;在onCreate()的時候&#xff0…

C++運算符與類型轉換

除法/ 參與運算時,結果符號按照(為,–為,-或為-),兩個都是整型結果直接去除小數部分 -3/1-1 -3/-13 3/-13 除法 一律向0取整&#xff08;即直接切除小數部分&#xff09;。 取余% 參與運算為整型,結果符號和第一個相同(當結果不為0時) /* 21%63 -21%6-3 -21%-6-3 參與取余的運…

使用named_mutex實現鎖機制

介紹 named_mutex是一個進程鎖&#xff0c;考慮到進程和線程之間的區別區別&#xff1a;一個工作單元要想被稱作進程&#xff0c;它必須要有操作系統指派給他的地址空間&#xff0c;必須擁有進程ID&#xff0c;必須擁有狀態和進程表中的表項。進程和線程之間最大的區別是進程有…

Android Studio 突然出現很多紅色波浪線或紅色感嘆號解決方案

最近在開發過程中&#xff0c;某次打開Android工程之后&#xff0c;代碼了出現大量的紅色波浪線報錯提示&#xff0c;但是工程確可以正常編譯、正常打包&#xff0c;嘗試了很多方法都無法去掉&#xff0c;最后找到了最有效的解決方案&#xff0c;步驟如下&#xff1a; 1、刪掉…

安卓常用布局學習

線性布局 布局方向 水平 android:orientation“horizontal” 垂直android:orientation“vertical” gravity對齊方式–center 布局權重:視圖中剩余部分的面積所占比例 android:layout_weight“1”(數字) 水平布局:android:layout_width“0dp” 垂直布局:android:layout_heigh…

Android Canvas繪制帶箭頭的直線

先看下效果圖&#xff1a; 下面我們直接看代碼 我自定義了一個View&#xff0c;代碼如下&#xff1a; package com.davis.drawtrangle;import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; imp…

使用named_mutex實現讀寫鎖,實現進程之間讀共享寫獨占

代碼 代碼的名稱是read_write_mutex.h這個代碼可用&#xff0c;但是未優化&#xff0c;還存在冗余的代碼如果涉及到進程掛掉了&#xff0c;造成進程堵塞&#xff0c;如何解決&#xff1f;還未涉及 //#ifndef BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP #define BOOST_THREAD_PTHR…

Android Activity之間傳遞類對象

一、簡介 開發過程中&#xff0c;Activity之間傳遞數據是必不可少的&#xff0c;Android中使用Intent和Bundle作為數據載體&#xff0c;在Activity之間傳遞&#xff0c;對于基礎數據類型&#xff0c;Bundle已經提供了相關的put、set方法&#xff0c;而作為自定義的類型則需要有…

C++3個漢諾塔遞歸問題

3個漢諾塔問題A—>C 移動次數2^n-1 hannoni(int n,char a,char b,char c)把n個盤子借助b,從a移動到cmove(int n,char a,char c)把第n個盤子,從a移動到c #include<iostream> #include<cmath> using namespace std; //漢諾塔問題A--->C //2^n-1次移動次數 …

clion編譯器解決undefined reference to symbol ‘shm_open@@GLIBC_2.2.5‘

修改CMakelists文件 cmake_minimum_required(VERSION 3.17) project(mutex_learn)set(CMAKE_CXX_STANDARD 14)set(BOOST_ROOT "/usr/local/include/boost") #添加頭文件搜索路徑 include_directories(/usr/local/include) #添加庫文件搜索路徑 link_directories(/us…

Android 攔截或屏蔽返回鍵

在Android開發中我們常常會遇到需要攔截或屏蔽返回鍵的需求&#xff0c;對攔截后的返回鍵進行特殊操作。 監聽返回鍵有兩種方式 1、重寫OnBackPressed方法 Overridepublic void onBackPressed() {// 完全由自己控制返回鍵邏輯&#xff0c;系統不再控制&#xff0c;但是有個前…