HANDLE CreateSemaphore( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // SD LONG lInitialCount, // initial count LONG lMaximumCount, // maximum count LPCTSTR lpName // object name )
此函數可用來創建或打開一個信號量,先看參數說明:
lpSemaphoreAttributes:為信號量的屬性,一般可以設置為NULL
lInitialCount:信號量初始值,必須大於等於0,而且小於等於 lpMaximumCount,如果lInitialCount 的初始值為0,則該信號量默認為unsignal狀態,如果lInitialCount的初始值大於0,則該信號量默認為signal狀態,
lMaximumCount: 此值為設置信號量的最大值,必須大於0
lpName:信號量的名字,長度不能超出MAX_PATH ,可設置為NULL,表示無名的信號量。當lpName不為空時,可創建有名的信號量,若當前信號量名與已存在的信號量的名字相同時,則該函數表示打開該信號量,這時參數lInitialCount 和
lMaximumCount 將被忽略。
函數調用成功返回信號量句柄。
釋放信號量函數:
BOOL ReleaseSemaphore( HANDLE hSemaphore, // handle to semaphore
LONG lReleaseCount, // count increment amount
LPLONG lpPreviousCount // previous count);
參數說明:
hSemaphore:信號量句柄,
lReleaseCount:釋放的數量,一般完成一個等待后調用此函數釋放一個信號量,使得信號量平衡。
lpPreviousCount :存放以前信號量的數量 ,一般可為NULL.
打開信號量函數:
HANDLE OpenSemaphore( DWORD dwDesiredAccess, // access BOOL bInheritHandle, // inheritance option LPCTSTR lpName// object name );
此函數打開一個有名的信號量
參數說明:
dwDesiredAccess:對信號量的訪問權限,取值可以是SEMAPHORE_ALL_ACCESS,可對信號量執行盡可能多的操作;可以是SEMAPHORE_MODIFY_STATE,允許使用ReleaseSemaphore釋放信號量,達到修改信號量;還可以是SYNCHRONIZE,用等待函數異步的等待信號量變為signal狀態
bInheritHandle:如果為true,信號量句柄可被繼承,反之不可繼承。
lpName :信號量的名字。
別忘了最后使用完成后用CloseHandle()關閉信號量句柄
暫時API寫到此為止,以后還有關信號量的函數,再繼續添加。下面通過一個例子,來說明使用信號量來世線程同步的例子,要求創建三個線程,每個線程次打印十次ID,必須三個線程一次打印。注意:在使用WaitForSingleObject等待信號量句柄時,若信號量為signal狀態,則wait過后信號量自動減1,直到使用ReleaseSemaphore釋放信號量,信號量才可增加
代碼如下:
說明:創建控制台程序。
#include "stdafx.h"
#include <Windows.h>
DWORD WINAPI Thread_1(LPVOID param);
DWORD WINAPI Thread_2(LPVOID param);
DWORD WINAPI Thread_3(LPVOID param);
HANDLE hSM_1;
HANDLE hSM_2;
HANDLE hSM_3;
HANDLE hThread_1;
HANDLE hThread_2;
HANDLE hThread_3;
int _tmain(int argc, _TCHAR* argv[])
{
//創建三個信號量
hSM_1 = CreateSemaphore(NULL, 1, 1, L"A");//開始為signal狀態
hSM_2 = CreateSemaphore(NULL, 0, 1, L"B");//開始為unsignal狀態,等待hSM_1釋放
hSM_3 = CreateSemaphore(NULL, 0, 1, L"C");//開始為unsignal狀態,等待hSM_2
//創建三個線程
hThread_1 = CreateThread(NULL, 0, Thread_1, NULL, 0, NULL);
hThread_2 = CreateThread(NULL, 0, Thread_2, NULL, 0, NULL);
hThread_3 = CreateThread(NULL, 0, Thread_3, NULL, 0, NULL);
//等待三個線程都執行完
WaitForSingleObject(hThread_1, INFINITE);
WaitForSingleObject(hThread_2, INFINITE);
WaitForSingleObject(hThread_3, INFINITE);
//三個線程都執行完
printf("\n\n\t main end \n");
//關閉句柄
CloseHandle(hThread_1);
CloseHandle(hThread_2);
CloseHandle(hThread_3);
CloseHandle(hSM_1);
CloseHandle(hSM_2);
CloseHandle(hSM_3);
return 0;
}
DWORD WINAPI Thread_1(LPVOID param)
{
for (int i = 0; i < 10; i ++)
{
DWORD dwWait = WaitForSingleObject(hSM_1, INFINITE);
//每一個wait過后信號量的數量自動減1,這樣就達到了控制同步
printf("A");
ReleaseSemaphore(hSM_2, 1, NULL);
}
return 0;
}
DWORD WINAPI Thread_2(LPVOID param)
{
for (int i = 0; i < 10; i ++)
{
WaitForSingleObject(hSM_2, INFINITE);
printf("B");
ReleaseSemaphore(hSM_3, 1, NULL);
}
return 0;
}
DWORD WINAPI Thread_3(LPVOID param)
{
for (int i = 0; i < 10; i ++)
{
WaitForSingleObject(hSM_3, INFINITE);
printf("C ");
ReleaseSemaphore(hSM_1, 1, NULL);
}
return 0;
}
