线程同步之信号量
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()函数才返回。