基于visual c++之windows核心编程代码分析(12)使用信号量同步线程

我们编写多线程应用程序的时候,经常需要进行线程同步协作,我们来实践一下用信号量同步线程。请见代码实现与注释分析,

[cpp]  view plain  copy
  1. /* 头文件 */  
  2. #include <windows.h>  
  3. #include <stdio.h>  
  4. /* 常量定义 */  
  5. #define NUMTHREADS  4   
  6. /* 全局变量 */  
  7. HANDLE hSemaphore;  
  8. /* 函数声明 */  
  9. void UseSemaphore(void);  
  10. DWORD WINAPI SemaphoreThread(LPVOID lpParam);  
  11.   
  12. /************************************* 
  13. * int main(void) 
  14. * 功能    演示 
  15. * 
  16. * 参数    未使用 
  17. **************************************/  
  18. int main()  
  19. {  
  20.      UseSemaphore() ;  
  21. }  
  22. /************************************* 
  23. * DWORD WaitForAllThread(HANDLE hThread[], DWORD dwNumThread) 
  24. * 功能    等待指定的线程都结束 
  25. * 
  26. * 参数    HANDLE hThread[]    需要等待结束的线程句柄数组 
  27. *       DWORD dwNumThread   线程句柄数组的大小 
  28. **************************************/  
  29. DWORD WaitForAllThread(HANDLE hThread[], DWORD dwNumThread)  
  30. {  
  31.     // 等待所有线程结束  
  32.     DWORD dwWaitResult = WaitForMultipleObjects(  
  33.         dwNumThread,  
  34.         hThread,                // 线程句柄作为等待对象  
  35.         TRUE,  
  36.         INFINITE);  
  37.     switch (dwWaitResult)   
  38.         {  
  39.         case WAIT_OBJECT_0:   
  40.             printf("\nAll thread exit\n");   
  41.             break;   
  42.         default:   
  43.             printf("\nWait error: %u", GetLastError());   
  44.         }  
  45.     return 0;  
  46.   
  47. }  
  48.   
  49. /************************************* 
  50. * void UseSemaphore(void)  
  51. * 功能    演示UseSemaphore的使用方法 
  52. * 
  53. * 参数    未使用 
  54. **************************************/  
  55. void UseSemaphore(void)   
  56. {  
  57.     HANDLE hThread[NUMTHREADS];  
  58.     INT i;  
  59.     LONG lMax;  
  60.     CHAR cMax;  
  61.     // 打印信息获取输入  
  62.     printf("将创建%d个进程,获得信号量的进程可以向屏幕打印。\n"  
  63.         "请输入信号量的最大计数1~%d:",NUMTHREADS,NUMTHREADS);    
  64.     // 获得输入的字符  
  65.     cMax = getch();  
  66.     printf("%c\n",cMax);  
  67.     // 将字符转换为数字  
  68.     lMax = cMax & 0xF;  
  69.     if(lMax<0 || lMax>NUMTHREADS)  
  70.     {  
  71.         printf("请输入1-%d",NUMTHREADS);  
  72.     }  
  73.     // 创建信号量  
  74.     hSemaphore = CreateSemaphore(   
  75.         NULL,   // 默认安全属性  
  76.         lMax,   // 初始化计数器,用户输入  
  77.         lMax,   // 最大计数,用户输入  
  78.         NULL);  // 未命名  
  79.     if (hSemaphore == NULL)   
  80.     {  
  81.         printf("CreateSemaphore error: %d\n", GetLastError());  
  82.     }  
  83.     // 创建多个线程 访问共享资源  
  84.     for(i = 0; i < NUMTHREADS; i++)   
  85.     {         
  86.         hThread[i] = CreateThread(NULL, 0,   
  87.             SemaphoreThread,   
  88.             &i,         // 进程序号作为参数  
  89.             0, NULL);   
  90.         if (hThread[i] == NULL)   
  91.         {  
  92.             printf("CreateThread failed (%d)\n", GetLastError());  
  93.             return;  
  94.         }  
  95.     }  
  96.     // 等待所有线程都执行完成并退出  
  97.     WaitForAllThread(hThread,NUMTHREADS);  
  98. }  
  99.   
  100. /************************************* 
  101. * DWORD WINAPI SemaphoreThread(LPVOID lpParam)  
  102. * 功能    线程函数,读共享内存 
  103. * 
  104. * 参数    未使用 
  105. **************************************/  
  106. DWORD WINAPI SemaphoreThread(LPVOID lpParam)   
  107. {  
  108.     DWORD dwWaitResult;  
  109.     BYTE lpRead[16];  
  110.     //DWORD i = *(LPWORD)lpParam;       // 线程的编号  
  111.     DWORD dwPreviousCount;  
  112.   
  113.     DWORD j = 0;  
  114.     // 每个线程都将访问3次受限资源  
  115.     for(; j<3; j++)  
  116.     {         
  117.         // 线程可以在此进行一些操作  
  118.         // 以暂停随机长的时间模拟真实情况  
  119.         Sleep(rand()%1000);  
  120.         // 等待信号量  
  121.         dwWaitResult = WaitForSingleObject(   
  122.             hSemaphore,      // 信号量句柄  
  123.             INFINITE);       // 无限等待  
  124.         switch (dwWaitResult)   
  125.         {  
  126.         case WAIT_OBJECT_0:   
  127.             printf("\nProcess %d Gets Semaphore",GetCurrentThreadId());  
  128.             break;   
  129.         default:   
  130.             printf("\nprocess %u Wait error: %u",GetCurrentThreadId(), GetLastError());   
  131.         }  
  132.         // 获得信息量后访问受限资源  
  133.         // 以等待随机长时间模块真实情况  
  134.         Sleep(rand()%1000);  
  135.         // 释放信号量  
  136.         if (!ReleaseSemaphore(   
  137.             hSemaphore,             // 信号量句柄  
  138.             1,                      // 释放后计数器减1   
  139.             &dwPreviousCount) )     // 获得计数  
  140.         {  
  141.             printf("\nprocess %u ReleaseSemaphore error: %d", GetCurrentThreadId(), GetLastError());  
  142.         }  
  143.         else  
  144.         {  
  145.             printf("\nProcess %u release Semaphore, previous count is %u",  
  146.                 GetCurrentThreadId(), dwPreviousCount);  
  147.         }  
  148.     }  
  149.   
  150.     return 1;  
  151. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值