使用Semaphore进行线程同步
#include <windows.h>
#include <stdio.h>
#define MAX_SEM_COUNT 2
#define THREADCOUNT 3
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 //初始化资源为2
MAX_SEM_COUNT, // maximum count //初始化资源最大数为2
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;
dwWaitResult = WaitForSingleObject( //当线程使用WaitForSingleObject从ghSemaphore中获取到信号时,资源计数减少1,当ghSemaphore没有资源时,并且参数为INFINITE WaitForSingleObject会卡住
ghSemaphore, // handle to semaphore
INFINITE); // zero-second time-out interval
printf("Thread %d: wait succeeded\n", GetCurrentThreadId());
bContinue = FALSE;
// Simulate thread spending time on task
Sleep(5000);
// Release the semaphore when task is finished
if (!ReleaseSemaphore( // 该API使ghSemaphore的内部资源计数加1
ghSemaphore, // handle to semaphore
1, // increase count by one
NULL)) // not interested in previous count
{
printf("ReleaseSemaphore error: %d\n", GetLastError());
}
// The semaphore was nonsignaled, so a time-out occurred.
return TRUE;
}
上面的代码我启动了三个进程,为信号分配了两个资源,那么在程序开始时,有两个线程先通过WaitForSingleObject
获取到信号,此时信号的资源计数减到0,执行printf
,然后等5s,有一个线程调用了ReleaseSemaphore
,使资源计数加1,最后一个线程也执行printf
,等待5s,最后所有线程结束,程序退出