執行緒同步之Semaphore
執行緒同步之訊號量
Semaphore
訊號量。
它維護一個計數,當值大於0時,訊號量物件處於已傳信狀態。通常用數值表示可用資源的個數。
WaitForSingleObject()令訊號量減一;ReleaseSemaphore()令訊號量加一。
//Semaphore //this example is from msdn #include #include #define MAX_SEM_COUNT 6 #define THREADCOUNT 8 HANDLE ghSemaphore; DWORD WINAPI ThreadProc( LPVOID ); int main( void ) { 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 1; } // 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 1; } } // 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); return 0; } DWORD WINAPI ThreadProc( LPVOID lpParam ) { // lpParam not used in this example UNREFERENCED_PARAMETER(lpParam); DWORD dwWaitResult; BOOL bContinue=TRUE; while(bContinue) { // Try to enter the semaphore gate. dwWaitResult = WaitForSingleObject( ghSemaphore, // handle to semaphore 1L); // 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); // Release 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; } /* Thread 7752: wait succeeded Thread 9520: wait succeeded Thread 10852: wait succeeded Thread 5352: wait succeeded Thread 8164: wait succeeded Thread 10060: wait succeeded Thread 4800: wait timed out Thread 4516: wait timed out Thread 4516: wait timed out Thread 4800: wait timed out Thread 4800: wait timed out Thread 4800: wait succeeded Thread 4516: wait timed out Thread 4516: wait succeeded 請按任意鍵繼續. . . */
分析:
訊號量值為6,MAX_SEM_COUNT ,而用到訊號量的執行緒有8,THREADCOUNT,不包括main函式執行緒。所以前6個建立好的執行緒WaitForSingleObject()返回值為WAIT_OBJECT_0,不會阻塞。而接下來的執行緒WaitForSingleObject()返回值為 WAIT_TIMEOUT,它們等其他P操作成功的執行緒 Sleep(5)後做V操作,才能獲得WAIT_OBJECT_0返回值。
8個ThreadProc執行緒執行完畢,主函式中WaitForMultipleObjects()函式才返回。