首页 > 代码库 > 线程同步——内核对象实现线程同步——信号量

线程同步——内核对象实现线程同步——信号量

  1 /*  2   3 信号量内核对象  4     信号量与其它内核量相同,包含一个使用计数,除此之外还包含两个量。  5     一个最大资源计数和一个当前资源计数。  6     信号量规则如下:  7     如果当前资源计数大于0,那么信号量处于触发状态。  8     如果当前资源计数等于0,那么信号量处于未触发状态。  9     系统绝不会让当前资源计数变为负数。 10     当前资源计数绝不会大于最大资源计数。 11  12     下面我们看一下信号量的创建函数 13     HANDLE  CreateSemaphore( 14     LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,  15     LONG lInitialCount, 16     LONG lMaximumCount,  17     LPCSTR lpName ); 18 第一、四个参数同其他内核对象一样,就不过多介绍了。 19     第三个参数lInitialCount为当前资源计数,第四个参数lMaximumCount为最大资源计数 20  21     线程通过调用ReleaseSemaphore,来增加当前资源计数。 22     下面看ReleaseSemaphore函数: 23  24     BOOL ReleaseSemaphore(  25     HANDLE hSemaphore,  26     LONG lReleaseCount,   27     LPLONG lpPreviousCount ) ; 28 第一个参数hSemaphore,为信号量句柄,第二个参数lReleaseCount为增加资源数 29     第三个参数lpPreviousCount为返回当前资源计数,一般传入 NULL。 30  31     关于信号量需要注意的是,在递减当前资源计数时是以原子方式进行的。 32     但是递减完后,其它线程便可以访问资源,在这个时候先前线程也许并未结束, 33     所以信号量并不互斥,主要用于控制访问次数或者创建的线程数。 34  35 下面我们看一下使用步骤: 36   37  38 1) 39 //定义一个信号量 40 HANDLE g_hSemaphore  ; 41 2) 42 //创建一个信号量内核对象 43 g_hSemaphore = CreateSemaphore(NULL,0,5,NULL); 44 3) 45 //增加信号量当前资源数 46 ReleaseSemaphore(g_hSemaphore,5,NULL); 47 4) 48 //在线程函数中调用 49 DWORD WINAPI ThreadFunOne(PVOID pvParam)  50 { 51     while(1) 52     { 53         WaitForSingleObject(g_hSemaphore,INFINITE); 54         g_x++; 55         cout<<"我是ThreadFunOne:"<<g_x<<endl; 56     } 57     return 0; 58 } 59  60 */ 61  62 #include "windows.h" 63 #include "iostream" 64 using namespace std; 65 long g_x = 0 ; 66  67 //定义一个信号量 68 HANDLE g_hSemaphore  ;   69 //定义线程函数1 70 DWORD WINAPI ThreadFunOne(PVOID pvParam) ; 71  72 //定义线程函数2 73 DWORD WINAPI ThreadFunTwo(PVOID pvParam); 74  75 int main() 76 { 77  78     //创建一个信号量内核对象 79     g_hSemaphore = CreateSemaphore(NULL,0,5,NULL); 80  81     //增加信号量当前资源数 82     ReleaseSemaphore(g_hSemaphore,5,NULL); 83  84     //创建线程1 85     HANDLE hThreadOne = CreateThread(NULL,0,ThreadFunOne,0,0,NULL); 86     CloseHandle(hThreadOne); 87  88     //创建线程2 89     HANDLE hThreadTwo = CreateThread(NULL,0,ThreadFunTwo,0,0,NULL); 90     CloseHandle(hThreadTwo); 91  92     getchar(); 93     cout<<g_x<<endl; 94     return 0 ; 95 } 96  97 DWORD WINAPI ThreadFunOne(PVOID pvParam)  98 { 99     while(1)100     {101         WaitForSingleObject(g_hSemaphore,INFINITE);102         g_x++;103         cout<<"我是ThreadFunOne:"<<g_x<<endl;104     }105     return 0;106 }107 108 DWORD WINAPI ThreadFunTwo(PVOID pvParam)109 {110     while (1)111     {112         WaitForSingleObject(g_hSemaphore,INFINITE);113         g_x++;    114         cout<<"我是ThreadFunTwo:"<<g_x<<endl;115     }116     return 0;117 }