线程同步--信号量内核对象
信号量同步能够很好的解决线程执行顺序。
HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName );
第一个参数第四个参数和前面事件内核对象的一样。
第二个参数:表示当前可用资源数量。为0的时候,说明没有资源可用,线程进入阻塞状态。
第三个参数:表示可用资源的最大数。
当一个线程通过WaitForSingleObject函数得到资源之后,系统会自动将可用资源减一。
这是原子操作。可以放心使用!
当线程用完资源的时候可以使用
BOOL ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount );
这个函数将资源释放。
第一个参数:等待的内核句柄对象
第二个参数:释放资源的个数,一般为1.
第三个参数:返回当前可用资源的数量。
实例:
#include <iostream>#include <windows.h>using namespace std;#define MAX_THREAD 10HANDLE handle_single;char s = 'A' ;char sz[MAX_THREAD + 10 ];CRITICAL_SECTION cs;DWORD WINAPI ThreadProc(LPVOID lpParameter){WaitForSingleObject( handle_single , INFINITE );EnterCriticalSection(&cs);strcat( sz , &s );s++;LeaveCriticalSection(&cs);ReleaseSemaphore( handle_single , 1 , NULL );return 0;}int main(int argc, char* argv[]){HANDLE hand[MAX_THREAD];handle_single = CreateSemaphore( NULL , 0 , 1 , NULL );sz[0] = 'S';InitializeCriticalSection(&cs);for (int i = 0 ; i < MAX_THREAD ; ++i ){hand[i] = CreateThread( NULL , 0 , ThreadProc , NULL , 0 , NULL );}ReleaseSemaphore( handle_single , 1 , NULL );WaitForMultipleObjects( MAX_THREAD , hand , true , INFINITE );cout<<sz<<endl;for (i = 0 ; i < MAX_THREAD ; ++i ){CloseHandle( hand[i] );}CloseHandle(handle_single);return 0;}
显示结果:

由得到的结果可以知道,系统会记录申请资源的线程,然后逐一分配资源,应该是微软最常用的FIFO策略。
微软提供给了这么多同步使用的方法 ,他们基本上可以涵盖所有的同步事件只不过有一些书本举例不恰当,导致我们不容易理解!