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


目录
相关文章
|
存储 开发框架 开发者
QT C++焦点事件:多角度解析实用技巧与方法
QT C++焦点事件:多角度解析实用技巧与方法
2981 0
|
存储 C++
【C++】可变参数模板使用总结(简洁易懂,详细,含代码演示)
【C++】可变参数模板使用总结(简洁易懂,详细,含代码演示)
|
存储 Cloud Native 程序员
C++ Qt 事件(event)
C++ Qt 事件(event)
|
存储 设计模式 安全
【C++ 软件设计思路】多角度探索C++事件处理:以‘handlePowerEvent’函数为例
【C++ 软件设计思路】多角度探索C++事件处理:以‘handlePowerEvent’函数为例
314 2
|
10月前
|
程序员 编译器 C++
【实战指南】C++ lambda表达式使用总结
Lambda表达式是C++11引入的特性,简洁灵活,可作为匿名函数使用,支持捕获变量,提升代码可读性与开发效率。本文详解其基本用法与捕获机制。
361 79
|
测试技术 数据库 C++
Qt C++拖放事件探索之旅:多方法深入解析
Qt C++拖放事件探索之旅:多方法深入解析
1540 1
|
传感器 人工智能 算法
掌握C++中的状态-事件回调矩阵:打造强大的有限状态机
掌握C++中的状态-事件回调矩阵:打造强大的有限状态机
514 0
|
存储 自然语言处理 C++
【C++杂货铺】set 和 map 使用总结
【C++杂货铺】set 和 map 使用总结
160 0
|
NoSQL 编译器 Shell
C++可变参数使用总结
C++可变参数使用总结
|
调度 C++ 存储
C++11线程使用总结
C++11线程使用总结 std::thread 在 <thread> 头文件中声明,因此使用 std::thread 需包含 <thread> 头文件。 <thread> 头文件摘要 <thread> 头文件声明了 std::thread 线程类及 std::swap (交换两个线程对象)辅助函数。
1798 0