1. <nobr id="easjo"><address id="easjo"></address></nobr>

      <track id="easjo"><source id="easjo"></source></track>
      1. 
        

      2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
      3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>
          貴州做網站公司
          貴州做網站公司~專業!靠譜!
          10年網站模板開發經驗,熟悉國內外開源網站程序,包括DEDECMS,WordPress,ZBlog,Discuz! 等網站程序,可為您提供網站建設,網站克隆,仿站,網頁設計,網站制作,網站推廣優化等服務。我們專注高端營銷型網站,企業官網,集團官網,自適應網站,手機網站,網絡營銷,網站優化,網站服務器環境搭建以及托管運維等。為客戶提供一站式網站解決方案?。?!

          【并發編程六】c++進程通信——信號量(semaphore)

          來源:互聯網轉載 時間:2023-09-04 20:45:30

          【并發編程六】c++進程通信——信號量(semaphore)

          • 一、概述
          • 二、信號量
          • 三、原理
          • 四、過程
            • 1、進程A過程
            • 2、進程B過程
          • 五、demo
            • 1、進程A
            • 2、進程B
          • 六、輸出
          • 七、windows api介紹
            • 1. 創建信號量 CreateSemaphore()
            • 2. 打開信號量 OpenSemaphore()
            • 3. 等待 WaitForSingleObject()
            • 4. 遞增信號量的當前資源計數ReleaseSemaphore()
            • 5. 關閉句柄 CloseHandle()
          • 八、信號量使用場景

          為了防?多進程競爭共享資源,?造成的數據錯亂,所以需要保護機制,使得共享的資源,在任意時刻只能被?個進程訪問(或者有限個進程訪問)。正好,信號量就實現了這?保護機制。

          一、概述

          信號量的概念是由荷蘭計算機科學家艾茲赫爾·戴克斯特拉(Edsger W. Dijkstra)發明的,廣泛的應用于不同的操作系統中。在系統中,給予每一個進程一個信號量,代表每個進程目前的狀態,未得到控制權的進程會在特定地方被強迫停下來,等待可以繼續進行的信號到來。如果信號量是一個任意的整數,通常被稱為計數信號量(Counting semaphore),或一般信號量(general semaphore);如果信號量只有二進制的0或1,稱為二進制信號量(binary semaphore)

          • 信號量是操作系統提供的一種協調共享資源訪問的方法。信號量則由操作系統進行管理,地位高于進程,操作系統保證信號量的原子性。

          二、信號量

          信號量(英語:semaphore)又稱為信號標或者信號燈,是一個同步對象,用于保持在0至指定最大值之間的一個計數值。當線程完成一次對該semaphore對象的等待(wait)時,該計數值減一;當線程完成一次對semaphore對象的釋放(release)時,計數值加一。當計數值為0,則線程等待該semaphore對象不再能成功直至該semaphore對象變成signaled狀態。semaphore對象的計數值大于0,為signaled狀態;計數值等于0,為nonsignaled狀態。

          三、原理

          一個信號量 S 是個整型變量,它除了初始化外只能通過兩個標準原子操作:wait () 和 signal() 來訪問:

          • 操作 wait() 最初稱為 P(荷蘭語proberen,測試);成功則,S–;
          • 操作 signal() 最初稱為 V(荷蘭語verhogen,增加);成功則,S++;

          四、過程

          我們以windows api的接口為例,講解下信號量是如何在進程A和進程B間做到進程間同步的。

          1、進程A過程

          • 1.1、CreateSemaphore():創建一個名字為Semaphore的信號量,該信號量初始可使用的資源數為0。即S=0.
          • 1.2、WaitForSingleObject():等待信號量>0,就是等待信號量的資源數大于0時。成功后就是S–。(啟動進程A后,此處會一直等待,因為創建的信號量初始的值=0,直到進程B打開進程A的信號量,并且釋放一個可以使用的資源時,S變成1,才可以繼續,進行后面的程序)
          • 1.3、在屏幕打印文字。
          • 1.4、ReleaseSemaphore():釋放上面wait成功時占用的1個資源數。執行成功后就是S++。
          • 1.5、等待5s。

          2、進程B過程

          • 2.1、OpenSemaphore():打開進程A創建的信號量,名字為Semaphore
          • 2.2、ReleaseSemaphore():遞增信號量的當前資源計數,就是S++。S=1
          • 2.3、WaitForSingleObject():等待信號量>0,就是等待信號量的資源數大于0時。成功后就是S–。
          • 2.4、在屏幕打印文字。
          • 2.5、ReleaseSemaphore():釋放上面wait成功時占用的1個資源數。成功后就是S++。
          • 2.6、等待5s。

          五、demo

          1、進程A

          • main.cpp
          #include <windows.h> #include <iostream> using namespace std;#define BUF_SIZE 4096int main(int argc, TCHAR* argv[]) {cout << "processA:" << endl << endl;// 創建信號量HANDLE handle = CreateSemaphore(NULL,0,10,"Semaphore");cout << "創建信號量成功,并等待進程B釋放一個可以使用的資源數......." << endl<<endl;for (int i = 0; i < 5; i++){cout << "進入新號量等待區" << endl;DWORD ret = WaitForSingleObject(handle,100000);if (0 == ret){cout << "processA:" << i << ".....s--" << endl;}ReleaseSemaphore(handle , 1,NULL);cout << "釋放1個信號并等待5秒中....." << "s++" << endl << endl;Sleep(5000);} system("pause"); //等待其他進程讀取數據// 關閉句柄CloseHandle(handle);return 0; }
          • CmakeList.txt
          CMAKE_MINIMUM_REQUIRED(VERSION 3.8.0) PROJECT(process) ADD_EXECUTABLE(processA main.cpp) ADD_SUBDIRECTORY(processB) SET(EXECUTABLE_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/lib")

          2、進程B

          • main.cpp
          #include <iostream> #include <windows.h> using namespace std;#define BUF_SIZE 4096int main() {cout << "processB:" << endl << endl;// 打開共享的文件對象HANDLE handle = OpenSemaphore(SEMAPHORE_ALL_ACCESS, // 訪問標志TRUE, // 繼承標志"Semaphore"); // 信號量名if (nullptr != handle){cout << "打開信號量:成功" << endl;}else{cout << "打開信號量:失敗" << endl;}cout << "釋放1個可以使用的資源數:s++" << endl<<endl;ReleaseSemaphore(handle, 1, NULL);for (int i = 0; i < 5; i++){cout << "進入新號量等待區" << endl;DWORD ret = WaitForSingleObject(handle,100000);if (0 == ret){cout << "processB:" << i <<".....s--"<< endl;}ReleaseSemaphore(handle, 1, NULL);cout << "釋放1個信號并等待5秒中....." << "s++" << endl << endl;Sleep(5000);}system("pause");return 0; }
          • CmakeLists.txt
          CMAKE_MINIMUM_REQUIRED(VERSION 3.8.0)SET(TARGET "childprocess")ADD_EXECUTABLE(processB main.cpp)SET(LIBRARY_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/lib") SET(EXECUTABLE_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/lib")

          六、輸出

          構建、編譯、先啟動進程A,輸出如下。(備:因為創建信號量時,初始化資源數為0,即S=0,如果你不啟動進程B釋放可用的資源數,進程A在此處會等待直到超時)

          再啟動進程B輸出如下。

          七、windows api介紹

          本文我們以windows的api接口為例,其實Linux下接口原理是一樣的,用法也類似,我們不再過多介紹。

          1. 創建信號量 CreateSemaphore()

          函數說明:

          第一個參數表示安全控制,一般直接傳入NULL。
          第二個參數表示初始資源數量。
          第三個參數表示最大并發數量。
          第四個參數表示信號量的名稱,傳入NULL表示匿名信號量。

          HANDLE WINAPI CreateSemaphore( _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全屬性,通常為NULL_In_ LONG lInitialCount, // 可用資源數目,就是信號量S的初始值_In_ LONG lMaximumCount, // 信號量對象可處理的最大資源數,就是S的最大值_In_opt_ LPCTSTR lpName // 信號量的名稱,進程之間可共享 );

          2. 打開信號量 OpenSemaphore()

          函數說明:

          第一個參數表示訪問權限,對一般傳入SEMAPHORE_ALL_ACCESS。詳細解釋可以查看MSDN文檔。
          第二個參數表示信號量句柄繼承性,一般傳入TRUE即可。
          第三個參數表示名稱,不同進程中的各線程可以通過名稱來確保它們訪問同一個信號量。

          HANDLE WINAPI OpenSemaphore( _In_ DWORD dwDesiredAccess, // 訪問的權限_In_ BOOL bInheritHandle, // 子進程繼承信號量對象與否_In_ LPCTSTR lpName // 信號量對象名稱 );

          3. 等待 WaitForSingleObject()

          等待指定對象處于信號狀態或超時間隔已過。
          本文中,就是等待信號量S>0時,進入。如果信號量S<=0,那就是等待,直到設置的超時時間。

          DWORD WINAPI WaitForSingleObject( _In_ HANDLE hHandle, // 內核對象句柄_In_ DWORD dwMilliseconds // 單位,毫秒。對象被觸發前的等待時間,INFINITE表示無限時間阻塞等待,簡單來說就是死等 );

          4. 遞增信號量的當前資源計數ReleaseSemaphore()

          函數說明:

          第一個參數是信號量的句柄。
          第二個參數表示增加個數,必須大于0且不超過最大資源數量。
          第三個參數可以用來傳出先前的資源計數,設為NULL表示不需要傳出。

          BOOL WINAPI ReleaseSemaphore( _In_ HANDLE hSemaphore, // 信號量對象句柄_In_ LONG lReleaseCount, // 釋放使用的資源樹_Out_opt_ LPLONG lpPreviousCount // 一般設為null );

          當一個線程使用完信號量對象控制的有限資源后,應該調用ReleaseSemaphore,釋放使用的資源,使信號量對象的當前資源計數得到恢復

          5. 關閉句柄 CloseHandle()

          BOOL WINAPI CloseHandle( _In_ HANDLE hObject // 句柄 );

          八、信號量使用場景

          • 多進程訪問統一資源。
          • 資源限流。
            比如:數據庫連接池,同時進行連接的線程有數量限制,連接不能超過一定的數量,當連接達到了限制數量后,后面的線程只能排隊等前面的線程釋放了數據庫連接才能獲得數據庫連接。

          關于資源限流,我們舉例說下。
          1、一個廁所有3個坑,進廁所需要拿1個號牌(5毛錢一個號牌)。
          2、肯定要設置為信號量的初始值為S=3,就是廁所的號牌數量為3。
          3、進去一個人,號牌減1,S–。
          4、當進入3個人時,沒有號牌了,S=0,第四個人就要等待了,
          5、等待廁所中的其中一個人上完大號出來,把號牌交出去,S++,其他人才可以拿著號牌進去。
          (其實,你想想網站服務器控制并發訪問和限流,不也是這個原理嗎?)

          • 參考
            1、多線程面試題系列(8):經典線程同步 信號量Semaphore
            2、 信號量與管程
            3、 信號量及其使用和實現(超詳細)
            4、 維基百科-信號量
            4、 信號量限流,高并發場景不得不說的秘密
          標簽:sem-

          網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...

          在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...

          在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...

          d2c是什么牌子?D2C——中國首家設計師自由平臺。D2C是英文DESIGNER-TO-CUSTOMER(設計師對客戶)的縮寫。涵義是設計師通過“聚需求,團寶貝”的方式直接面向消費者,通過強大的營銷平臺,設計師直接傳達自己的設計理念和相關設計產品,達到出售原創產品的目的,使設計師的原創設計價值得到充分的體現,客戶得到人性化的貼心服務。D2C希望通過努力,整合各方資源,給設計師及設計師品牌提供良好的...

          石家莊新百廣場是什么區?是橋西區。石家莊新百廣場在橋西區。地址:河北省石家莊市中山西路139號(近中華街)。穿過新百廣場(東)(西三室內繪畫館)的線路:1號、1號、6號、11號、30號、34號、61號、68號、108號、118號、317號、326號、368號..途經新百廣場(西)的線路:1路、快車1路、游客1路、游客5路、6路、11路、30路、34路、61路、93路、快車107路、192路、317...

          太原到平遙古城?您好,從太原開車到平遙古城大概需要100-110公里,具體看路線和實際路況。謝謝你。平遙古城是一座具有2700多年歷史的文化名城,始建于西周宣王時期(公元前827-782年)。子明洪武三年(公元1370年)重建后,基本保持了原有格局。與第二批國家歷史文化名城四川閬中、云南麗江、安徽歙縣并稱為“保存最完好的四大古城”,也是唯一一個以古城整體成功申報世界文化遺產的古縣城。進入古城不需要...

          TOP
          国产初高中生视频在线观看|亚洲一区中文|久久亚洲欧美国产精品|黄色网站入口免费进人
          1. <nobr id="easjo"><address id="easjo"></address></nobr>

              <track id="easjo"><source id="easjo"></source></track>
              1. 
                

              2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
              3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>