C++ 事件(event)使用总结-阿里云开发者社区

开发者社区> AI小浩> 正文

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


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较
原文:C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较 使用Task,await,async,异步执行事件(event),不阻塞UI线程和不跨线程执行UI更新   使用Task,await,async 的异步模式 去执行事件(event) 解决不阻塞UI线程和不夸跨线程执行UI更新报错的最佳实践,附加几种其他方式比较 由于是Winform代码和其他原因,本文章只做代码截图演示,不做界面UI展示,当然所有代码都会在截图展示。
3335 0
Android EventBus 3.0.0 使用总结
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/53065112 本文出自【赵彦军的博客】 前言 EventBus框架 EventBus是一个通用的叫法,例如Google出品的Guava,Guava是一个庞大的库,EventBus只是它附带的一个小功能,因此实际项目中使用并不多。
961 0
[C#]委托和事件(详细讲解)
引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在。
574 0
Windows Phone 8初学者开发—第5部分:布局和事件基础
原文 Windows Phone 8初学者开发—第5部分:布局和事件基础 原文地址: http://channel9.msdn.com/Series/Windows-Phone-8-Development-for-Absolute-Beginners/Part-5-Basics-of-Layout-and-Events 系列地址:http://channel9.
702 0
winform 使用快捷键来触发按钮事件
WinForm中快捷键与组合按键的设置   第一种方法。。代码复杂,操作简单的快捷键 新建一个空白窗体 每个窗体都有这样3个事件:KeyDown、KeyPress、KeyUp,KeyDown和KeyPress都是按键按下事件,但KeyDown用的是KeyCode跟键盘各个按键相对应,它对应Keys枚举,用起来比较方便;而KeyPress用的是KeyChar,这个就要找ASC II编码了,不方便。
932 0
+关注
400
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载