C++ 事件(event)使用总结

简介: C++ 事件(event)使用总结

 事件最常用在多线程同步互斥机制。


常用的函数有:


1、CreateEvent 创建事件。


函数原型如下所示,一共四个参数:


HANDLE CreateEvent(


 LPSECURITY_ATTRIBUTES lpEventAttributes, // SECURITY_ATTRIBUTES结构指针,可为NULL

 BOOL bManualReset,     // 手动/自动

                                    // TRUE:表示手动,在WaitForSingleObject后必须手动调用ResetEvent清除信号

                                   // FALSE:表示自动,在WaitForSingleObject后,系统自动清除事件信号

 BOOL bInitialState,        //初始状态,FALSE为无信号,TRUE为有信号

 LPCTSTR lpName         //事件的名称

   );


2、SetEvent:设置为激活触发状态。


3、ResetEvent:设置为未激活触发状态。


4、WaitForSingleObject:检测信号,如果未激活,代码就会处于挂起状态,不再往下执行。


下面是多线程同步的示例:

#include <tchar.h> 
#include <iostream>
#include <wtypes.h>
using namespace std;
DWORD WINAPI ThreadProc(LPVOID lpParam);
DWORD WINAPI ThreadProc2(LPVOID lpParam);
DWORD g_dwThreadID;
DWORD g_dwThreadID2;
UINT g_nTickets = 300;  
HANDLE g_hEvent1 = NULL;
HANDLE g_hEvent2 = NULL;
CRITICAL_SECTION g_cs;
int ThreadCout = 0;
int main(int argc, _TCHAR* argv[])
{
  cout << "Main thread is running." << endl;
  InitializeCriticalSection(&g_cs);//初始化临界区
  HANDLE hHandle = CreateThread(NULL, 0, ThreadProc, NULL, 0, &g_dwThreadID);
  ThreadCout++;
  HANDLE hHandle2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, &g_dwThreadID2);
  ThreadCout++;
  g_hEvent1 = CreateEvent(NULL, FALSE, TRUE, NULL);  //备注5:g_hEvent1 = CreateEvent(NULL, TRUE,  TRUE, NULL);
  g_hEvent2 = CreateEvent(NULL, FALSE, TRUE, NULL);  //备注5:g_hEvent2 = CreateEvent(NULL, TRUE,  TRUE, NULL);
  ResetEvent(g_hEvent1);
  ResetEvent(g_hEvent2);
  SetEvent(g_hEvent1);
  while (TRUE)
  {
    EnterCriticalSection(&g_cs);
    int nCount = ThreadCout;
    LeaveCriticalSection(&g_cs);
    if (nCount == 0)
    {
      cout << "Main break" << endl;
      break;
    }
  }
  Sleep(1000);    //备注4
  CloseHandle(hHandle);
  CloseHandle(hHandle2);
  DeleteCriticalSection(&g_cs);
  cout << "Main End " << endl;
  system("pause");
  return 0;
}
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
  while (TRUE)
  {
    WaitForSingleObject(g_hEvent1, INFINITE);
    cout << "线程1:" << g_dwThreadID << " thread is running." << endl;
    EnterCriticalSection(&g_cs);
    int temp = g_nTickets;
    LeaveCriticalSection(&g_cs);
    cout << "线程1:" << g_dwThreadID << " thread is temp." << endl;
    if (temp > 0)
    {
      Sleep(100);  //Sleep(1000)   
      cout << "线程1:" << g_dwThreadID << " sell ticket : " << temp << endl;
      EnterCriticalSection(&g_cs);
      g_nTickets--;
      LeaveCriticalSection(&g_cs);
      SetEvent(g_hEvent2);
    }
    else
    {
      cout << "线程1 break" << endl;
      SetEvent(g_hEvent2);//没有这个ThreadProc2不能终止   
      break;
    }
  }
  EnterCriticalSection(&g_cs);
  ThreadCout--;
  LeaveCriticalSection(&g_cs);
  cout << "线程1 end" << endl;
  return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParam)
{
  while (TRUE)
  {
    WaitForSingleObject(g_hEvent2, INFINITE);
    cout << "线程2: " << g_dwThreadID2 << " thread is running." << endl;
    EnterCriticalSection(&g_cs);
    int temp = g_nTickets;
    LeaveCriticalSection(&g_cs);
    if (temp > 0)
    {
      Sleep(100);  //Sleep(1000)   //备注2
      cout << "线程2:" << g_dwThreadID2 << " sell ticket : " << temp << endl;
      EnterCriticalSection(&g_cs);
      g_nTickets--;
      LeaveCriticalSection(&g_cs);
      SetEvent(g_hEvent1);      
    }
    else
    {
      cout << "线程2 break" << endl;      
      SetEvent(g_hEvent1);//同样的问题,没有这个ThreadProc不能终止
      break;
    }
  }
  EnterCriticalSection(&g_cs);
  ThreadCout--;
  LeaveCriticalSection(&g_cs);
  cout << "线程2 end" << endl;
  return 0;
}

执行结果如下图:

tt.png


目录
相关文章
|
7月前
|
存储 开发框架 开发者
QT C++焦点事件:多角度解析实用技巧与方法
QT C++焦点事件:多角度解析实用技巧与方法
1378 0
|
7月前
|
存储 设计模式 安全
【C++ 软件设计思路】多角度探索C++事件处理:以‘handlePowerEvent’函数为例
【C++ 软件设计思路】多角度探索C++事件处理:以‘handlePowerEvent’函数为例
127 2
|
存储 Cloud Native 程序员
C++ Qt 事件(event)
C++ Qt 事件(event)
|
7月前
|
测试技术 数据库 C++
Qt C++拖放事件探索之旅:多方法深入解析
Qt C++拖放事件探索之旅:多方法深入解析
562 1
|
7月前
|
传感器 人工智能 算法
掌握C++中的状态-事件回调矩阵:打造强大的有限状态机
掌握C++中的状态-事件回调矩阵:打造强大的有限状态机
148 0
|
监控 安全 C++
在不熟悉C/C++情况下,hook windows事件
本文讲的是在不熟悉C/C++情况下,hook windows事件,WMI(Windows 管理规范)是基于Windows操作系统的管理数据和操作的基础架构。可以编写WMI脚本或应用程序来自动执行远程计算机上的管理任务,但是WMI会将管理数据提供给操作系统和产品的其他部分。
1667 0