zoukankan      html  css  js  c++  java
  • Windows多线程同步系列之三-----事件对象

    事件是一个内核事件,内核事件是什么呢,我理解也不深入也不好说,暂且理解为一个内核维护的数据类型吧通过内核事件同步主要

    的方法是对事件的信号有和无来进行同步。

     

    比如当我们一个线程进入一段临界代码(独占代码段,不可多个线程同时访问)那么这时候我们将事件对象设置为无信号状态。那么另外

    一个线程便会在等待这样一个事件对象,直到该事件对象执行完临界代码,然后将事件对象设为有信号状态,此时便可以该线程便可进

    临界代码段。

     

    利用事件对象进行同步主要有以下几个API;

    该函数用于创建一个匿名的事件对象,返回值为创建的事件对象

    第一个参数为安全属性,当为NULL,设置为默认安全属性

    第二个参数为手动或自动改变时间对象的信号状态。TRUE为手动。FALSE为自动

    第三个参数为事件对象的初始化状态,TRUE为初始有信号状态,FALSE为初始无信号状态

    第四个是事件对象的名称,NULL说明未匿名事件对象

     

    一般情况下,我们选择创建一个默认安全属性,手工置位,初始为有信号状态,未命名的事件对象

    该函数将事件对象置为有信号状态,成功则返回非零值,失败则返回零值。

    该函数将事件对象置为无信号状态,成功则返回非零值,失败则返回零值

    关闭事件对象,在程序结束之前。

    该函数用于等待事件对象是否为有信号状态,如果为信号状态则返回,否则一直阻塞。其传入连个参数一个是事件对象,一个是超时

    间隔。当第二个参数为INFINITE的时候该函数将一直阻塞知道事件被置为有信号状态。

     

     

    我们还是以典型的卖票的例子来进行测试,代码实现如下:

     1 #include <windows.h>
     2 #include <stdio.h>
     3 
     4 static int number=10;
     5 HANDLE SigHand;
     6 
     7 DWORD WINAPI ThreadOne(LPVOID lpParameter)
     8 {
     9     printf("窗口1售票开始:
    ");
    10     while(1)
    11     {
    12         WaitForSingleObject(SigHand,INFINITE);
    13         ResetEvent(SigHand);
    14         if(number>0)
    15         {
    16             printf("窗口1售出第%d张票...
    ",number);
    17             number--;
    18             Sleep(1000);        
    19         }
    20         SetEvent(SigHand);
    21         Sleep(100);
    22     }
    23     return 0;
    24 }
    25 DWORD WINAPI ThreadTwo(LPVOID lpParameter)
    26 {
    27     printf("窗口2售票开始:
    ");
    28     while(1)
    29     {
    30         WaitForSingleObject(SigHand,INFINITE);
    31         ResetEvent(SigHand);
    32         if(number>0)
    33         {
    34             printf("窗口2售出第%d张票...
    ",number);
    35             Sleep(1000);
    36             number--;
    37         }
    38         SetEvent(SigHand);
    39         Sleep(100);
    40     }
    41     return 0;
    42 }
    43 
    44 
    45 int main()
    46 {
    47     HANDLE HOne,HTwo;
    48     
    49     printf("***********************vpoet******************
    ");
    50     HOne=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);
    51     HTwo=CreateThread(NULL,0,ThreadTwo,NULL,0,NULL);
    52     SigHand=CreateEvent(NULL,TRUE,TRUE,NULL);
    53     CloseHandle(HOne);
    54     CloseHandle(HTwo);
    55     while(TRUE)
    56     {
    57         if(number==0)
    58         {
    59             printf("不好意思,票卖完了!
    ");
    60             CloseHandle(SigHand);
    61             return 0;
    62         }
    63         else
    64         {
    65             continue;
    66         }    
    67     }
    68     
    69     return 0;
    70 }

    运行截图:

  • 相关阅读:
    hdu 1548 升降梯
    hdu 2544 hdu 1874 poj 2387 Dijkstra 模板题
    hdu 4463 有一条边必须加上 (2012杭州区域赛K题)
    poj 1679 判断MST是不是唯一的 (次小生成树)
    poj 1751 输出MST中新加入的边
    poj 2349 求MST中第S大的权值
    HDU 4389 X mod f(x) (数位DP)
    HDU 5908 Abelian Period (暴力)
    HDU 5907 Find Q (水题)
    HDU 4514 湫湫系列故事――设计风景线 (树形DP)
  • 原文地址:https://www.cnblogs.com/vpoet/p/4686093.html
Copyright © 2011-2022 走看看