在開發軟體的過程中,多線程的程式往往需要實現相互連訊,比如幾個線程添加一個訊息到隊列裡,而另一個線程在睡眠時,就需要喚醒那個線程來處理事情。在這其中,就需要使用到訊號量來進行同步。CreateSemaphore是建立訊號量,ReleaseSemaphore是增加訊號量。
函數CreateSemaphore和ReleaseSemaphore聲明如下:
WINBASEAPI
__out
HANDLE
WINAPI
CreateSemaphoreA(
__in_opt LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
__in LONG lInitialCount,
__in LONG lMaximumCount,
__in_opt LPCSTR lpName
);
WINBASEAPI
__out
HANDLE
WINAPI
CreateSemaphoreW(
__in_opt LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
__in LONG lInitialCount,
__in LONG lMaximumCount,
__in_opt LPCWSTR lpName
);
#ifdef UNICODE
#define CreateSemaphore CreateSemaphoreW
#else
#define CreateSemaphore CreateSemaphoreA
#endif // !UNICODE
lpSemaphoreAttributes是訊號量的安全屬性。
lInitialCount是初始化的訊號量。
lMaximumCount是允許訊號量增加到最大值。
lpName是訊號量的名稱。
WINAPI
ReleaseSemaphore(
__in HANDLE hSemaphore,
__in LONG lReleaseCount,
__out_opt LPLONG lpPreviousCount
);
hSemaphore是要增加的訊號量控制代碼。
lReleaseCount是增加的計數。
lpPreviousCount是增加前的數值返回。
調用函數的例子如下:
#001 //線程運行函數。
#002 //在這裡可以使用類裡的成員,也可以讓衍生類別實現更強大的功能。
#003 //蔡軍生 2007/10/10 QQ:9073204 深圳
#004 DWORD CThreadSemaphore::Run(void)
#005 {
#006 //輸出到調試視窗。
#007 ::OutputDebugString(_T("Run()線程函數運行\r\n"));
#008
#009 //
#010 const LONG cMax = 10;
#011 m_hSemaphore = CreateSemaphore(
#012 NULL, // 預設的安全屬性。
#013 0, // 初始化為0個訊號量。
#014 cMax, // 最大為10個訊號量。
#015 NULL); // 不命名。
#016
#017 if (m_hSemaphore == NULL)
#018 {
#019 return -1;
#020 }
#021
#022 //
#023 const int nMaxObjs = 2;
#024 HANDLE hWaitObjects[nMaxObjs] = {m_hEventExit,m_hSemaphore};
#025
#026 //線程迴圈。
#027 for (;;)
#028 {
#029 DWORD dwRet = WaitForMultipleObjects(nMaxObjs,hWaitObjects,FALSE,INFINITE);
#030 if (dwRet == WAIT_TIMEOUT)
#031 {
#032 //可以繼續運行。
#033 TCHAR chTemp[128];
#034 wsprintf(chTemp,_T("CThreadSemaphore::Run() ThreadID=%d\r\n"),m_dwThreadID);
#035 ::OutputDebugString(chTemp);
#036
#037 //目前沒有做什麼事情,就讓線程釋放一下CPU。
#038 Sleep(10);
#039 }
#040 else if (dwRet == WAIT_OBJECT_0)
#041 {
#042 //退出線程。
#043 ::OutputDebugString(_T("Run() 退出線程\r\n"));
#044 break;
#045 }
#046 else if (dwRet == WAIT_OBJECT_0+1)
#047 {
#048 //可以繼續運行。
#049 TCHAR chTemp[128];
#050 wsprintf(chTemp,_T("CThreadSemaphore::Run() Semaphore,ThreadID=%d\r\n"),m_dwThreadID);
#051 ::OutputDebugString(chTemp);
#052
#053 //
#054
#055 }
#056 else if (dwRet == WAIT_ABANDONED)
#057 {
#058 //出錯。
#059 ::OutputDebugString(_T("Run() 線程出錯\r\n"));
#060 return -1;
#061 }
#062 }
#063
#064 //
#065 if (m_hSemaphore)
#066 {
#067 CloseHandle(m_hSemaphore);
#068 m_hSemaphore = NULL;
#069 }
#070
#071 return 0;
#072 }
#073
第11行就是建立訊號量。
第29行等訊號量事件和退出事件。
#001
#002 //
#003 //增加訊號量
#004 //蔡軍生 2007/10/10 QQ:9073204 深圳
#005 //
#006 void IncSemaphore(void)
#007 {
#008 if (m_hSemaphore)
#009 {
#010 if (!ReleaseSemaphore(
#011 m_hSemaphore, // 要增加的訊號量。
#012 1, // 增加1.
#013 NULL) ) // 不想返回前一次訊號量。
#014 {
#015
#016 }
#017 }
#018 }
#019
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/caimouse/archive/2007/10/10/1819116.aspx