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


      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 }

     

  • 相关阅读:
    5 -- Hibernate的基本用法 --5 1 持久化类的要求
    5 -- Hibernate的基本用法 --5 深入理解持久化对象
    Java -- POI -- 随笔汇总
    jdk 自带的数据库Derby使用
    SpringMVC中 -- @RequestMapping的作用及用法
    Hibernate -- Dao层 -- CURD -- 随记
    JAVA WEB -- request
    SpringMVC -- @RequestMapping -- 随记
    Navicat -- Oracle -- 错误锦集
    Tomcat -- 启动错误 -- 解决锦集
  • 原文地址:https://www.cnblogs.com/yfyzy/p/3916196.html
Copyright © 2020-2023  润新知