1. 程式人生 > >多執行緒同步-訊號量(深入理解Semaphore)

多執行緒同步-訊號量(深入理解Semaphore)

多執行緒同步之Semaphore (主要解決生產者消費者問題)

一 信標Semaphore
信標核心物件用於對資源進行計數。它們與所有核心物件一樣,包含一個使用數量,但是它們也包含另外兩個帶符號的3 2位值,一個是最大資源數量,一個是當前資源數量。最大資源數量用於標識信標能夠控制的資源的最大數量,而當前資源數量則用於標識當前可以使用的資源的數量。

為了正確地說明這個問題,讓我們來看一看應用程式是如何使用信標的。比如說,我正在開發一個伺服器程序,在這個程序中,我已經分配了一個能夠用來存 放客戶機請求的緩衝區。我對緩衝區的大小進行了硬編碼,這樣它每次最多能夠存放5個客戶機請求。如果5個請求尚未處理完畢時,一個新客戶機試圖與伺服器進 行聯絡,那麼這個新客戶機的請求就會被拒絕,並出現一個錯誤,指明伺服器現在很忙,客戶機應該過些時候重新進行聯絡。當我的伺服器程序初始化時,它建立一 個執行緒池,裡面包含5個執行緒,每個執行緒都準備在客戶機請求到來時對它進行處理。

開始時,沒有客戶機提出任何請求,因此我的伺服器不允許執行緒池中的任何執行緒成為可排程執行緒。但是,如果3個客戶機請求同時到來,那麼執行緒池中應該有 3個執行緒處於可排程狀態。使用信標,就能夠很好地處理對資源的監控和對執行緒的排程,最大資源數量設定為5,因為這是我進行硬編碼的緩衝區的大小。當前資源 數量最初設定為0,因為沒有客戶機提出任何請求。當客戶機的請求被接受時,當前資源數量就遞增,當客戶機的請求被提交給伺服器的執行緒池時,當前資源數量就 遞減。

信標的使用規則如下:

? 如果當前資源的數量大於0,則發出信標訊號。

? 如果當前資源數量是0,則不發出信標訊號。

? 系統決不允許當前資源的數量為負值。

? 當前資源數量決不能大於最大資源數量。

當使用信標時,不要將信標物件的使用數量與它的當前資源數量混為一談。

二 API

Semaphore function Description
Creates or opens a named or unnamed semaphore object.
Creates or opens a named or unnamed semaphore object and returns a handle to the object.
Opens an existing named semaphore object.
Increases the count of the specified semaphore object by a specified amount.

三 例項
多執行緒(C++)同步Semaphore#include <windows.h>
多執行緒(C++)同步Semaphore#include 
<stdio.h>
多執行緒(C++)同步Semaphore
多執行緒(C++)同步Semaphore
#define MAX_SEM_COUNT 6
多執行緒(C++)同步Semaphore
#define THREADCOUNT 12
多執行緒(C++)同步Semaphore
多執行緒(C++)同步SemaphoreHANDLE ghSemaphore;
多執行緒(C++)同步Semaphore
多執行緒(C++)同步SemaphoreDWORD WINAPI ThreadProc( LPVOID );
多執行緒(C++)同步Semaphore
多執行緒(C++)同步Semaphore
void main()
多執行緒(C++)同步Semaphore
{
多執行緒(C++)同步Semaphore    HANDLE aThread[THREADCOUNT];
多執行緒(C++)同步Semaphore    DWORD ThreadID;
多執行緒(C++)同步Semaphore    
int i;
多執行緒(C++)同步Semaphore
多執行緒(C++)同步Semaphore    
// Create a semaphore with initial and max counts of MAX_SEM_COUNT
多執行緒(C++)同步Semaphore

多執行緒(C++)同步Semaphore    ghSemaphore 
= CreateSemaphore( 
多執行緒(C++)同步Semaphore        NULL,           
// default security attributes
多執行緒(C++)同步Semaphore
        MAX_SEM_COUNT,  // initial count
多執行緒(C++)同步Semaphore
        MAX_SEM_COUNT,  // maximum count
多執行緒(C++)同步Semaphore
        NULL);          // unnamed semaphore
多執行緒(C++)同步Semaphore

多執行緒(C++)同步Semaphore    
if (ghSemaphore == NULL) 
多執行緒(C++)同步Semaphore    
{
多執行緒(C++)同步Semaphore        printf(
"CreateSemaphore error: %d\n", GetLastError());
多執行緒(C++)同步Semaphore        
return;
多執行緒(C++)同步Semaphore    }

多執行緒(C++)同步Semaphore
多執行緒(C++)同步Semaphore    
// Create worker threads
多執行緒(C++)同步Semaphore

多執行緒(C++)同步Semaphore    
for( i=0; i < THREADCOUNT; i++ )
多執行緒(C++)同步Semaphore    
{
多執行緒(C++)同步Semaphore        aThread[i] 
= CreateThread( 
多執行緒(C++)同步Semaphore                     NULL,       
// default security attributes
多執行緒(C++)同步Semaphore
0,          // default stack size
多執行緒(C++)同步Semaphore
                     (LPTHREAD_START_ROUTINE) ThreadProc, 
多執行緒(C++)同步Semaphore                     NULL,       
// no thread function arguments
多執行緒(C++)同步Semaphore
0,          // default creation flags
多執行緒(C++)同步Semaphore
&ThreadID); // receive thread identifier
多執行緒(C++)同步Semaphore

多執行緒(C++)同步Semaphore        
if( aThread[i] == NULL )
多執行緒(C++)同步Semaphore        
{
多執行緒(C++)同步Semaphore            printf(
"CreateThread error: %d\n", GetLastError());
多執行緒(C++)同步Semaphore            
return;
多執行緒(C++)同步Semaphore        }

多執行緒(C++)同步Semaphore    }

多執行緒(C++)同步Semaphore
多執行緒(C++)同步Semaphore    
// Wait for all threads to terminate
多執行緒(C++)同步Semaphore

多執行緒(C++)同步Semaphore    WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);
多執行緒(C++)同步Semaphore
多執行緒(C++)同步Semaphore    
// Close thread and semaphore handles
多執行緒(C++)同步Semaphore

多執行緒(C++)同步Semaphore    
for( i=0; i < THREADCOUNT; i++ )
多執行緒(C++)同步Semaphore        CloseHandle(aThread[i]);
多執行緒(C++)同步Semaphore
多執行緒(C++)同步Semaphore    CloseHandle(ghSemaphore);
多執行緒(C++)同步Semaphore}

多執行緒(C++)同步Semaphore
多執行緒(C++)同步SemaphoreDWORD WINAPI ThreadProc( LPVOID lpParam )
多執行緒(C++)同步Semaphore
{
多執行緒(C++)同步Semaphore    DWORD dwWaitResult; 
多執行緒(C++)同步Semaphore    BOOL bContinue
=TRUE;
多執行緒(C++)同步Semaphore
多執行緒(C++)同步Semaphore    
while(bContinue)
多執行緒(C++)同步Semaphore    
{
多執行緒(C++)同步Semaphore        
// Try to enter the semaphore gate.
多執行緒(C++)同步Semaphore

多執行緒(C++)同步Semaphore        dwWaitResult 
= WaitForSingleObject( 
多執行緒(C++)同步Semaphore            ghSemaphore,   
// handle to semaphore
多執行緒(C++)同步Semaphore
3L);           // zero-second time-out interval
多執行緒(C++)同步Semaphore

多執行緒(C++)同步Semaphore        
switch (dwWaitResult) 
多執行緒(C++)同步Semaphore        

多執行緒(C++)同步Semaphore            
// The semaphore object was signaled.
多執行緒(C++)同步Semaphore
case WAIT_OBJECT_0: 
多執行緒(C++)同步Semaphore                
// TODO: Perform task
多執行緒(C++)同步Semaphore
                printf("Thread %d: wait succeeded\n", GetCurrentThreadId());
多執行緒(C++)同步Semaphore                bContinue
=FALSE;            
多執行緒(C++)同步Semaphore
多執行緒(C++)同步Semaphore                
// Simulate thread spending time on task
多執行緒(C++)同步Semaphore
                Sleep(5);
多執行緒(C++)同步Semaphore
多執行緒(C++)同步Semaphore                
for(int x =0; x<10; x++)
多執行緒(C++)同步Semaphore                    printf(
"Thread %d task!\n",GetCurrentThreadId());
多執行緒(C++)同步Semaphore
多執行緒(C++)同步Semaphore                
// Relase the semaphore when task is finished
多執行緒(C++)同步Semaphore

多執行緒(C++)同步Semaphore                
if (!ReleaseSemaphore( 
多執行緒(C++)同步Semaphore                        ghSemaphore,  
// handle to semaphore
多執行緒(C++)同步Semaphore
1,            // increase count by one
多執行緒(C++)同步Semaphore
                        NULL) )       // not interested in previous count
多執行緒(C++)同步Semaphore
{
多執行緒(C++)同步Semaphore                    printf(
"ReleaseSemaphore error: %d\n", GetLastError());
多執行緒(C++)同步Semaphore                }

多執行緒(C++)同步Semaphore                
break
多執行緒(C++)同步Semaphore
多執行緒(C++)同步Semaphore            
// The semaphore was nonsignaled, so a time-out occurred.
多執行緒(C++)同步Semaphore
case WAIT_TIMEOUT: 
多執行緒(C++)同步Semaphore                printf(
"Thread %d: wait timed out\n", GetCurrentThreadId());
多執行緒(C++)同步Semaphore                
break
多執行緒(C++)同步Semaphore        }

多執行緒(C++)同步Semaphore    }

多執行緒(C++)同步Semaphore    
return TRUE;
多執行緒(C++)同步Semaphore}

相關推薦

執行同步-訊號深入理解Semaphore

多執行緒同步之Semaphore (主要解決生產者消費者問題) 一 信標Semaphore 信標核心物件用於對資源進行計數。它們與所有核心物件一樣,包含一個使用數量,但是它們也包含另外兩個帶符號的3 2位值,一個是最大資源數量,一個是當前資源數量。最大資源數量用於標識信標

執行同步-互斥物件深入理解Mutex

多執行緒之執行緒同步Mutex (功能與Critial Sections相同,但是屬於核心物件,訪問速度較慢,可以被不同程序呼叫)一 Mutex 互斥物件(mutex)核心物件能夠確保執行緒擁有對單個資源的互斥訪問權。實際上互斥物件是因此而得名的。互斥物件包含一個使用數量,

PYTHON——執行訊號Semaphore

  訊號量也是一把鎖,用來控制執行緒併發數的。   BoundedSemaphore或Semaphore管理一個內建的計數 器,每當呼叫acquire()時-1,呼叫release()時+1。       計數器不能小於0,當計數器為 0時,acquire()將阻塞執行緒至同

秒殺執行第八篇 經典執行同步 訊號Semaphore

前面介紹了關鍵段CS、事件Event、互斥量Mutex在經典執行緒同步問題中的使用。本篇介紹用訊號量Semaphore來解決這個問題。 首先也來看看如何使用訊號量,訊號量Semaphore常用有三個函式,使用很方便。下面是這幾個函式的原型和使用說明。 第一個 Create

Linux執行——使用訊號同步執行

訊號量、同步這些名詞在程序間通訊時就已經說過,在這裡它們的意思是相同的,只不過是同步的物件不同而已。但是下面介紹的訊號量的介面是用於執行緒的訊號量,注意不要跟用於程序間通訊的訊號量混淆,關於用於程序間通訊的訊號量的詳細介紹可以參閱我的另一篇博文:。相似地,執行緒同步是控制執

執行訊號的簡單使用 GCD

基本概念 關於iOS開發中,多執行緒基本的概念和基本使用,我在這裡就不在重複說了。但是為了照顧到有的同學可能還不是對基本的概念不熟悉,可以參考一下這篇文章併發其實很簡單 說說訊號量,併發數 如果你有計算機基礎,那麼下面這段話應該很簡單就能理解 訊號量就是一個資源計數器,對訊號

linux 執行訊號 sem_init

1. 什麼是訊號量 linux sem 訊號量是一種特殊的變數,訪問具有原子性, 用於解決程序或執行緒間共享資源引發的同步問題。 使用者態程序對 sem 訊號量可以有以下兩種操作: 等待訊號量 當訊號量值為 0 時,程式等待;當訊號量值大於 0 時,訊號量減 1,程式

【Windows原理】執行同步-訊號

#include "stdafx.h" #include <windows.h> int g_num = 0; HANDLE g_hSemaphore = nullptr; DWORD WINAPI ThreadProc(LPVOID lpParam) { for

執行同步與互斥3

在進行多執行緒程式設計時,難免還要碰到兩個問題,那就執行緒間的互斥與同步: 執行緒同步是指執行緒之間所具有的一種制約關係,一個執行緒的執行依賴另一個執行緒的訊息,當它沒有得到另一個執行緒的訊息時應等待,直到訊息到達時才被喚醒。 執行緒互斥是指對於共享的程序系統資源,在各單個執行緒訪問時的排它性。當有若干個執行

執行訊號Semaphore及原理

一、訊號量(Semaphore) 重入鎖ReentrantLock是獨佔模式,一次都只允許一個執行緒訪問一個資源,而訊號量是共享模式,也就是說可以指定多個執行緒,同時訪問某一個資源。 Semaphore的兩個構造方法: public Semaphore(int pe

執行同步----訊號

上篇文章《執行緒同步---睡覺與喚醒》遺留了一個問題,就是會出現死鎖的情況。所以為了解決這個問題,又要引入一個新的同步概念,那就是訊號量。     起初我個人在理解的時候陷入了一個奇怪的圈子,就總憑感覺和名字認為這個訊號量是不是一個儲存我之前失效訊號的容器,讓後在需要之前訊號

執行處理訊號

include include include define BOUNDARY 5 int tasks = 10; pthread_mutex_t tasks_mutex; pthread_cond_t tasks_cond; stati

執行同步--訊號Semaphore

訊號量Semaphore常用有三個函式,使用很方便。下面是這幾個函式的原型和使用說明。 第一個 CreateSemaphore 函式功能:建立訊號量 函式原型: HANDLE WINAPI Crea

【Qt執行訊號】Qsemaphore

訊號量 怎麼簡單的給自己解釋這個機制呢? 那就借這個小程式碼解釋吧 QSemaphore freeBytes(80); QSemaphore usedBytes(0); freeBytes.acquire(); buffer[i%BufferSize]

C++執行同步之事件Event

一、事件(Event)原理解析 1、執行緒同步Event,主要用於執行緒間的等待通知。 2、核心物件中,事件核心物件是個最基本的物件。 3、事件包含一個使用計數(與所有核心物件一樣),一個用於指明該事件是個自動重置的事件還是人工重置的事件的布林值,另一個用

SDL2.0 執行使用訊號

// SDL_Thread.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <windows.h> #include "SDL/

併發:等待執行完成的CountDownLatch倒數計時器

CountDownLatch允許一個或多個執行緒等待其他執行緒完成操作。 假如有這樣一個需求:我們需要解析一個Excel裡多個sheet的資料,此時可以考慮使用多執行緒,每個執行緒解析一個sheet裡的資料,等到所有的sheet都解析完之後,程式需要提示解析完成。在這個需求中,要實現主執行緒等待

Java執行面試知識點彙總超詳細總結

一、sleep()方法、wait()方法、yeild()方法、interrupt()方法、notify()、notifyAll()方法 1、sleep()方法: sleep方法為Thread的靜態方法; sleep方法的作用是讓執行緒休眠指定時間,在時間到

執行爬取圖片生產者-消費者模式

通過生產者-消費者模式實現多執行緒爬取圖片:   1、生產者通過不斷爬取網頁中圖片的url存入圖片佇列中   2、消費者通過圖片佇列中的url爬取圖片並下載到本地   3、多執行緒的方式,爬取與下載同時進行,直到子執行緒結束,輸出爬取時間   1 #多執行緒下載圖片 2 #生產者

跨平臺的執行互斥訪問控制Mutex和Critical_Section

<1>首先解決跨平臺   現在比較常用的平臺式Linux平臺和windows平臺,所以我們應該針對不同的平臺引用不同的標頭檔案 //平臺相關定義 #ifdef __linux #define OS_LINUX #endif #if defined(_WIN32)