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

  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 }

 

原文地址:https://www.cnblogs.com/yfyzy/p/3916196.html