信號量

信號量對線程的同步方式與前面幾種方法不同,信號量允許多個線程同時使用共享資源,這與操作系統中的PV操作相同。它指出了同時訪問共享資源的線程最大數目。它允許多個線程在同一時刻訪問同一資源,但是需要限制在同一時刻訪問此資源的最大線程數目。在用CreateSemaphore創建信號量時即要同時指出允許的最大資源計數和當前可用資源計數。一般是將當前可用資源計數設置爲最大資源計數。每增加一個線程對共享資源的訪問,當前可用資源計數就會減1,只要當前可用資源計數是大於0的,就可以發出信號量信號。但是當前可用計數減小到0時則說明當前佔用資源的線程數已經達到了所允許的最大數目,不能再允許其他線程的進入,此時的信號量信號將無法發出。線程在處理完共享資源後,應在離開的同時通過ReleaseSemaphore()函數將當前可用資源計數加1。在任何時候當前可用資源計數決不可能大於最大資源計數。 
CreateSemaphore() 創建一個信號量 
OpenSemaphore() 打開一個信號量 
WaitForSingleObject() 等待信號量

ReleaseSemaphore() 釋放信號量 

#include <windows.h>
#include <iostream>

using namespace std;

HANDLE g_hSemaphore = NULL;
int tickets = 100;

DWORD WINAPI FUNCPROC1(LPVOID) {
	while (TRUE) {
		WaitForSingleObject(g_hSemaphore, INFINITE);
		if (tickets > 0) {
			cout << "thread1 sell ticket: "<<tickets-- << endl;
			ReleaseSemaphore(g_hSemaphore, 1, NULL);
		}
		else {
			ReleaseSemaphore(g_hSemaphore, 1, NULL);
			break;
		}
	}

	return 0;
}

DWORD WINAPI FUNCPROC2(LPVOID) {
	while (TRUE) {
		WaitForSingleObject(g_hSemaphore, INFINITE);
		if (tickets > 0) {
			cout << "thread2 sell ticket: " << tickets-- << endl;
			ReleaseSemaphore(g_hSemaphore, 1, NULL);
		}
		else {
			ReleaseSemaphore(g_hSemaphore, 1, NULL);
			break;
		}
	}

	return 0;
}

int main() 
{
	//設置信號量的初始計數和最大計數都爲1
	g_hSemaphore = CreateSemaphore(NULL, 1, 1, NULL);
	HANDLE hThread1 = CreateThread(NULL, 0, FUNCPROC1, NULL, 0, NULL);
	HANDLE hThread2 = CreateThread(NULL, 0, FUNCPROC2, NULL, 0, NULL);

	WaitForSingleObject(hThread1, INFINITE);
	WaitForSingleObject(hThread2, INFINITE);

	CloseHandle(hThread1);
	CloseHandle(hThread2);
	CloseHandle(g_hSemaphore);

	return 0;
}

總結:
1、互斥量、事件、信號量都是內核對象,可用於進程間的線程同步;而臨界區是進程內對象,只能用於進程內的線程同步。互斥量與臨界區的作用非常相似,但互斥量是可以命名的,也就是說它可以跨越進程使用。所以創建互斥量需要的資源更多,如果只爲了在進程內部使用的話,臨界區會帶來速度上的優勢並能夠減少資源佔用量。因爲互斥量是跨進程的,互斥量一旦被創建,就可以通過名字打開它。 


2、事件和其他幾個同步方法的不同在於事件的主要作用不是保護共享的資源,而是用於等待某個事件和在特定的事件發生時發送信號,以協調線程之間的動作。
 
3、信號量與其他同步方法的區別在於它允許一個以上的線程同時訪問共享資源,而其他線程同步方法都保證同時只能有一個線程訪問共享的資源。信號量主要是用於資源計數,能夠控制有限用戶使用資源。通過互斥量可以指定資源被獨佔的方式使用,但如果有下面一種情況通過互斥量就無法處理,比如現在一位用戶購買了一份三個併發訪問許可的數據庫系統,可以根據用戶購買的訪問許可數量來決定有多少個線程/進程能同時進行數據庫操作,這時候如果利用互斥量就沒有辦法完成這個要求,信號量對象可以說是一種資源計數器。
發佈了24 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章