Synchronization 進程鎖

  • Boost.Interprocess允許多個進程同時使用共享內存。因為共享內存從定義上來說是進程間共享的,所以Boost.Interprocess需要支持某種同步。
  • 想到同步,我們會想到C++11標準庫中的類或Boost.Thread。但是這些類只能用來同步同一進程內的線程,它們不支持不同進程的同步。不過,由于兩種情況下面臨的挑戰是一樣的,所以概念也是一樣的。
  • 在多線程應用程序中,同步對象(如mutexes和條件變量)駐留在同一個地址空間中,因此所有線程都可以使用,而共享內存的挑戰是,獨立的進程需要共享這些對象。例如,如果一個進程創建了一個mutex,那么它就需要以某種方式從另一個進程中訪問。
  • Boost.Interprocess提供了兩種同步對象:匿名對象直接存儲在共享內存中,這使得它們對所有進程自動可用。命名對象由操作系統管理,不存儲在共享內存中,可以通過名稱從程序中引用(named_mutex)

Example 33.12. Using a named mutex with boost::interprocess::named_mutex

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <iostream>using namespace boost::interprocess;int main()
{managed_shared_memory managed_shm{open_or_create, "shm", 1024};int *i = managed_shm.find_or_construct<int>("Integer")();named_mutex named_mtx{open_or_create, "mtx"};named_mtx.lock();++(*i);std::cout << *i << '\n';named_mtx.unlock();
}
  • Example?33.12?creates and uses a named mutex using the class?boost::interprocess::named_mutex, which is defined in?boost/interprocess/sync/named_mutex.hpp.
  • boost::interprocess::named_mutex的構造函數期望得到一個參數,指定是否應該創建或打開mutex,以及mutex的名稱。每個知道這個名字的進程都可以打開同一個mutex。要訪問共享內存中的數據,程序需要通過調用成員函數lock()來獲得mutex的所有權。由于mutexes一次只能由一個進程擁有,所以另一個進程可能需要等待,直到mutex被unlock()釋放。一旦一個進程擁有了一個mutex的所有權,它就擁有了對mutex所保護的資源的獨占性訪問權。在示例33.12中,資源是一個類型為int的變量,它被遞增并寫入標準輸出流。
  • 如果示例程序被多次啟動,每個實例都會打印一個比前一個值遞增1的值。由于有了mutex,不同進程之間對共享內存和變量本身的訪問是同步的。

Example?33.13.?Using an anonymous mutex with?interprocess_mutex

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <iostream>using namespace boost::interprocess;int main()
{managed_shared_memory managed_shm{open_or_create, "shm", 1024};int *i = managed_shm.find_or_construct<int>("Integer")();interprocess_mutex *mtx =managed_shm.find_or_construct<interprocess_mutex>("mtx")();mtx->lock();++(*i);std::cout << *i << '\n';mtx->unlock();
}
  • Example?33.13?uses an anonymous mutex of type?boost::interprocess::interprocess_mutex, which is defined in?boost/interprocess/sync/interprocess_mutex.hpp. In order for the mutex to be accessible for all processes, it is stored in the shared memory.?
  • 例33.13的行為與前一個完全相同。唯一不同的是mutex,它現在直接存儲在共享內存中。這可以通過類 boost::interprocess::managed_shared_memory 中的成員函數 construct() 或 find_or_construct() 來實現。除了lock(),boost::interprocess::named_mutex和boost::interprocess::interprocess_mutex都提供了成員函數try_lock()和timed_lock()。它們的行為與標準庫和Boost.Thread中的對應函數完全相同。如果需要遞歸互斥,Boost.Interprocess提供了兩個類:boost::interprocess::named_recursive_mutex和boost::interprocess::interprocess_recursive_mutex

  • 互斥保證了對共享資源的獨占訪問,而條件變量則控制了誰在什么時候擁有獨占訪問權。一般來說,Boost.Interprocess提供的條件變量與C++11標準庫和Boost.Thread提供的條件變量的工作原理類似。它們具有類似的接口,這使得這些庫的用戶在Boost.Interprocess中使用這些變量時,會立即感到賓至如歸。

Example?33.14.?Using a named condition with?boost::interprocess::named_condition

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <iostream>using namespace boost::interprocess;int main()
{managed_shared_memory managed_shm{open_or_create, "shm", 1024};int *i = managed_shm.find_or_construct<int>("Integer")(0);named_mutex named_mtx{open_or_create, "mtx"};named_condition named_cnd{open_or_create, "cnd"};scoped_lock<named_mutex> lock{named_mtx};while (*i < 10){if (*i % 2 == 0){++(*i);named_cnd.notify_all();named_cnd.wait(lock);}else{std::cout << *i << std::endl;++(*i);named_cnd.notify_all();named_cnd.wait(lock);}}named_cnd.notify_all();shared_memory_object::remove("shm");named_mutex::remove("mtx");named_condition::remove("cnd");
}
  • Example?33.14?uses a condition variable of type?boost::interprocess::named_condition, which is defined in?boost/interprocess/sync/named_condition.hpp. Because it is a named variable, it does not need to be stored in shared memory.?
  • 例33.14使用了一個類型為boost::interprocess::named_condition的條件變量,它定義在boost/interprocess/sync/named_condition.hpp中。因為它是一個命名變量,所以不需要存儲在共享內存中。
  • 應用程序使用一個 while 循環來遞增一個類型為 int 的變量,該變量存儲在共享內存中。雖然變量隨著循環的每次迭代而遞增,但它只會在每第二次迭代時被寫入標準輸出流--只寫奇數。每當變量遞增1時,條件變量命名為_cnd的成員函數wait()被調用。一個鎖--在例33.14中,名為鎖的變量--被傳遞給這個成員函數。這是基于RAII的習慣,即在構造函數中取得一個mutex的所有權,并在destructor中釋放它。
  • 這個鎖是在while循環之前創建的,并且在整個程序執行過程中擁有mutex的所有權。然而,如果將其作為參數傳遞給wait(),鎖就會自動釋放。條件變量用于等待指示等待結束的信號。同步是由成員函數wait()和notify_all()控制的。當程序調用wait()時,相應的mutex的所有權被釋放。然后,程序會一直等待,直到對同一個條件變量調用notify_all()。啟動時,例33.14似乎并沒有什么作用。在while循環內將變量i從0增到1后,程序通過調用wait()等待信號。為了發射信號,需要啟動第二個程序實例。
  • 第二個實例在進入 while 循環之前,試圖取得同一個 mutex 的所有權。由于第一個實例通過調用wait()釋放了mutex,所以成功了。因為變量已經被遞增了一次,第二個實例執行if表達式的else分支,并將當前值寫入標準輸出流。然后將值遞增1。現在第二個實例也調用wait()。然而,在這之前,它調用notify_all(),這確保了兩個實例的正確合作。第一個實例得到通知,并試圖再次獲得mutex的所有權,而這個mutex仍然由第二個實例擁有。然而,由于第二個實例在調用notify_all()后立即調用wait(),它會自動釋放所有權,所以第一個實例將在此時獲得所有權。兩個實例交替進行,遞增共享內存中的變量。但是,只有一個實例將值寫入標準輸出流。當變量達到值10時,while循環就結束了。為了避免讓另一個實例永遠等待信號,循環結束后再調用一次notify_all()。在終止之前,共享內存、mutex和條件變量被銷毀。
  • 就像有兩種類型的mutexes--一種是必須存儲在共享內存中的匿名類型,另一種是命名類型--條件變量也有兩種類型。例33.15是使用匿名條件變量重寫的上一個例子。

Example?33.15.?Using an anonymous condition with?interprocess_condition

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/interprocess_condition.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <iostream>using namespace boost::interprocess;int main()
{managed_shared_memory managed_shm{open_or_create, "shm", 1024};int *i = managed_shm.find_or_construct<int>("Integer")(0);interprocess_mutex *mtx =managed_shm.find_or_construct<interprocess_mutex>("mtx")();interprocess_condition *cnd =managed_shm.find_or_construct<interprocess_condition>("cnd")();scoped_lock<interprocess_mutex> lock{*mtx};while (*i < 10){if (*i % 2 == 0){++(*i);cnd->notify_all();cnd->wait(lock);}else{std::cout << *i << std::endl;++(*i);cnd->notify_all();cnd->wait(lock);}}cnd->notify_all();shared_memory_object::remove("shm");
}
  • 例33.15的工作原理和上一個完全一樣,同樣需要啟動兩次才能將int變量遞增十次。除了mutexes和條件變量,Boost.Interprocess還支持semaphores和文件鎖。Semaphores與條件變量類似,只是它們不區分兩種狀態,而是基于一個計數器。文件鎖的行為類似于mutexes,只是它們用于硬盤上的文件,而不是內存中的對象。
  • 就像C++11標準庫和Boost.Thread區分不同類型的mutexes和鎖一樣,Boost.Interprocess提供了幾種mutexes和鎖。例如,mutexes可以是獨占的,也可以是非獨占的。如果多個進程需要同時讀取數據,這很有幫助,因為只需要一個獨占的互斥來寫入數據。不同的鎖類可以將RAII習語應用于單個mutexes。
  • 除非使用匿名同步對象,否則名稱應該是唯一的。即使mutexes和條件變量是基于不同類的對象,但對于由Boost.Interprocess封裝的操作系統依賴性接口來說,這不一定成立。在Windows上,mutexes和條件變量都使用相同的操作系統函數。如果兩個對象使用相同的名稱,每種類型的對象都有一個,那么程序在Windows上將無法正常運行。?

參考鏈接

  • Synchronization

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

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

相關文章

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;但是有個前…

C++遞歸斐波那契數列

第一種 //斐波那契數列 // 0 1 1 … //從第1個開始 代碼 #include<iostream> #include<cmath> using namespace std; //斐波那契數列 // 0 1 1 ... //從第1個開始 int f(int n) {int m; if(n1)return 0;if(n2)return 1;elsemf(n-1)f(n-2);return m;} int mai…

Android onActivityResult中requestCode與resultCode區別

想要了解requestCode與resultCode的區別&#xff0c;我們需要先了解以下三個方法的用法&#xff1a; startActivityForResult(Intent intent, Int requestCode) setResut(int resultCode, Intent intent) onActivityResult(int requestCode, int resultCode, Intent intent) …

使用named_mutex和named_condition配合實現讀寫鎖

代碼 代碼的名稱是read_write_mutex.h初步優化如果涉及到進程掛掉了&#xff0c;造成進程堵塞&#xff0c;如何解決&#xff1f;還未涉及 #include <boost/interprocess/sync/named_condition.hpp> #include <boost/interprocess/sync/named_mutex.hpp>namespace …

C++的輸入與輸出

輸入與輸出 輸入:從外部輸入設備(鍵盤)向計算機輸入數據 輸出:從計算機向外部輸出設備(顯示屏)輸出數據 C使用流對象實現 使用流對象cin與cout,將標準輸入輸出流庫的頭文件iostream包含到源文件 #include<iostream>//標準輸入輸出庫 using namespace std;//使用標準命…

Android 動態計算ListView的高度

目錄一、簡介二、效果圖三、代碼實現一、簡介 在Android開發的過程中有的時候我們需要手動計算ListView的高度&#xff0c;比如說&#xff0c;ScrollView中嵌套ListView的時候&#xff0c;我們就需要手動精確計算ListView的高度了。 如果ListView的Item高度是固定的話還好計算…

DjangoRestFramework(drf實現五個接口)

安裝&#xff1a;pip install djangorestframework 在使用drf之前&#xff0c;先 使用原生Django實現5個接口 models.py from django.db import modelsclass Book(models.Model):namemodels.CharField(max_length53)pricemodels.IntegerField() views.py from app01 impor…