多執行緒同步-訊號量(深入理解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. |
三 例項
#include <windows.h>
#include <stdio.h>
#define MAX_SEM_COUNT 6
#define THREADCOUNT 12
HANDLE ghSemaphore;
DWORD WINAPI ThreadProc( LPVOID );
void main()
{
HANDLE aThread[THREADCOUNT];
DWORD ThreadID;
int i;
// Create a semaphore with initial and max counts of MAX_SEM_COUNT
ghSemaphore = CreateSemaphore(
NULL, // default security attributes
MAX_SEM_COUNT, // initial count
MAX_SEM_COUNT, // maximum count
NULL); // unnamed semaphore
if (ghSemaphore == NULL)
{
printf("CreateSemaphore error: %d\n", GetLastError());
return;
}
// Create worker threads
for( i=0; i < THREADCOUNT; i++ )
{
aThread[i] = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) ThreadProc,
NULL, // no thread function arguments
0, // default creation flags
&ThreadID); // receive thread identifier
if( aThread[i] == NULL )
{
printf("CreateThread error: %d\n", GetLastError());
return;
}
}
// Wait for all threads to terminate
WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);
// Close thread and semaphore handles
for( i=0; i < THREADCOUNT; i++ )
CloseHandle(aThread[i]);
CloseHandle(ghSemaphore);
}
DWORD WINAPI ThreadProc( LPVOID lpParam )
{
DWORD dwWaitResult;
BOOL bContinue=TRUE;
while(bContinue)
{
// Try to enter the semaphore gate.
dwWaitResult = WaitForSingleObject(
ghSemaphore, // handle to semaphore
3L); // zero-second time-out interval
switch (dwWaitResult)
{
// The semaphore object was signaled.
case WAIT_OBJECT_0:
// TODO: Perform task
printf("Thread %d: wait succeeded\n", GetCurrentThreadId());
bContinue=FALSE;
// Simulate thread spending time on task
Sleep(5);
for(int x =0; x<10; x++)
printf("Thread %d task!\n",GetCurrentThreadId());
// Relase the semaphore when task is finished
if (!ReleaseSemaphore(
ghSemaphore, // handle to semaphore
1, // increase count by one
NULL) ) // not interested in previous count
{
printf("ReleaseSemaphore error: %d\n", GetLastError());
}
break;
// The semaphore was nonsignaled, so a time-out occurred.
case WAIT_TIMEOUT:
printf("Thread %d: wait timed out\n", GetCurrentThreadId());
break;
}
}
return TRUE;
}
相關推薦
多執行緒同步-訊號量(深入理解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)