windows多线程(七) 事件event

前面说的互斥量Mutex与关键段CriticalSection都不能实现线程的同步,只能实现互斥,接下来我们用时间event就可以实现线程的同步了,事件也是一个内核对象。

一、相关函数说明

(一) 创建事件
1.函数原型

HANDLE WINAPI CreateEventW(
                _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
                _In_ BOOL bManualReset,
                _In_ BOOL bInitialState,
                _In_opt_ LPCWSTR lpName
                );
2.参数说明
  • 第一个参数表示安全控制,一般直接传入NULL。
  • 第二个参数确定事件是手动置位还是自动置位,传入TRUE表示手动置位,传入FALSE表示自动置位。如果为自动置位,则对该事件调用WaitForSingleObject()后会自动调用ResetEvent()使事件变成未触发状态。
  • 第三个参数表示事件的初始状态,传入TRUR表示已触发。
  • 第四个参数表示事件的名称,传入NULL表示匿名事件。
(二) 打开事件
1.函数原型

HANDLE WINAPI OpenEventW(
                _In_ DWORD dwDesiredAccess,
                _In_ BOOL bInheritHandle,
                _In_ LPCWSTR lpName
                );
2.参数说明
  • 第一个参数表示访问权限,对事件一般传入EVENT_ALL_ACCESS。
  • 第二个参数表示事件句柄继承性,一般传入TRUE即可。
  • 第三个参数表示名称,不同进程中的各线程可以通过名称来确保它们访问同一个事件。
(三) 触发事件
1.函数原型

BOOL WINAPI SetEvent(
              _In_ HANDLE hEvent
            );
2.参数说明
  • 函数说明:每次触发后,必有一个或多个处于等待状态下的线程变成可调度状态。
  • hEvent 为要触发的事件的句柄(内核对象)
(四)、 将事件设为末触发
1.函数原型

BOOL WINAPI ResetEvent(
              _In_ HANDLE hEvent
            );
2.参数说明
  • hEvent 为要触发的事件的句柄(内核对象)

二、实例

前面我们用关键段和互斥量无法实现线程同步,在前面的程序中,我们可以实现对全局资源互斥访问,即每个线程给全局资源加一,现在使用事件可以时间线程同步,即实现每个线程按顺序依次给全局资源加一,代码如下:



//使用事件进行线程同步

#include<iostream>
#include <windows.h>

using namespace std;

CRITICAL_SECTION g_csVar;
HANDLE g_event;
const int THREAD_NUM = 10;
int g_Num = 0;

DWORD WINAPI  Func(LPVOID);

int main()
{
    g_event = CreateEvent(NULL, false, false, NULL);    //初始化事件为未触发状态
    InitializeCriticalSection(&g_csVar);
    DWORD  ThreadId[THREAD_NUM];
    HANDLE handle[THREAD_NUM];
    int i = 0;
    while (i < THREAD_NUM)
    {
        handle[i] = CreateThread(NULL, 0, Func, &i, 0, &ThreadId[i]);
        WaitForSingleObject(g_event, INFINITE); //等待事件被触发
        i++;
    }
    WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);

    CloseHandle(g_event);
    DeleteCriticalSection(&g_csVar);
    return 0;
}

DWORD WINAPI Func(LPVOID p)
{
    int nThreadNum = *(int*)p;

    EnterCriticalSection(&g_csVar);
    cout << "线程编号为:" << nThreadNum << " 给全局资源g_Num 加1,现在给全局资源g_Num值为:" << ++g_Num << endl;
    LeaveCriticalSection(&g_csVar);
    SetEvent(g_event);  //触发事件
    return 0;
}

运行结果如下所示:

原文地址:https://www.cnblogs.com/ay-a/p/9114006.html

时间: 2024-08-09 17:30:55

windows多线程(七) 事件event的相关文章

转--- 秒杀多线程第六篇 经典线程同步 事件Event

阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇 一个经典的多线程同步问题> <秒杀多线程第五篇 经典线程同步关键段CS> 上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的“线程所有权”特性所以关键段只能用于线程的互斥而不能用于同步.本篇介绍用事件Event来尝试解决这个线程同步问题. 首先介绍下如何使用事件.事件Event实际上是个内核对象,它的使用非常方便.下面列出一些常用的函数. 第一个 CreateEvent 函数功能:创建事件 函数原型: HANDLEC

秒杀多线程第六篇 经典线程同步 事件Event

阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇 一个经典的多线程同步问题> <秒杀多线程第五篇 经典线程同步关键段CS> 上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的"线程所有权"特性所以关键段只能用于线程的互斥而不能用于同步.本篇介绍用事件Event来尝试解决这个线程同步问题. 首先介绍下如何使用事件.事件Event实际上是个内核对象,它的使用非常方便.下面列出一些常用的函数. 第一个 CreateEvent 函数功能:创建事件 函数原

向Windows内核驱动传递用户层定义的事件Event,并响应内核层的通知

完整的程序在下载:http://download.csdn.net/detail/dijkstar/7913249 用户层创建的事件Event是一个Handle句柄,和内核中的创建的内核模式下的KEVENT是一个东西.因此,在应用层创建的事件,可以在内核层获得并使用.这一部分的原理,见张帆编著的<Windows驱动技术详解>章节8.5.4,P237页: 程序是来自于<Windows驱动技术详解>章节8.5.4(驱动程序和应用程序交互事件对象)和章节10.2.1(DPC定时器). 首

Windows多线程编程总结

Windows 多线程编程总结 keyword:多线程 线程同步 线程池 内核对象 1 内核对象 1 .1 内核对象的概念 内核对象是内核分配的一个内存块,这样的内存块是一个数据结构,表示内核对象的各种特征.而且仅仅能由内核来訪问.应用程序若须要訪问内核对象,须要通过操作系统提供的函数来进行,不能直接訪问内核对象( Windows 从安全性方面来考虑的). 内核对象通过 Create* 来创建,返回一个用于标识内核对象的句柄,这些句柄 (而不是内核对象)可在创建进程范围内使用,不可以被传递到其它

windows多线程同步

概述 任何单个应用程序都不能完全使该处理器达到满负荷.当一个线程遇到较长等待时间事件时,同步多线程还允许另一线程中的指令使用所有执行单元.例如,当一个线程发生高速缓存不命中,另一个线程可以继续执行.同步多线程是 POWER5? 和 POWER6? 处理器的功能,可与共享处理器配合使用. SMT 对于商业事务处理负载的性能优化可达30%.在更加注重系统的整体吞吐量而非单独线程的吞吐量时,SMT 是一个很好地选择. 但是并非所有的应用都能通过SMT 取得性能优化.那些性能受到执行单元限制的应用,或者

Windows多线程多任务设计初步(转)

Windows多线程多任务设计初步 [前言:]当前流行的Windows操作系统,它能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软件是当今普遍采用的方法,进程和线程的概念的出现,对提高软件的并行性有着重要的意义.现在的应用软件无一不是多线程多任务处理,单线城的软件是不可想象的.因此掌握多线程多任务设计方法对每个程序员都是必需要掌握的.本文针对多线程技术在应用中经常遇到的问题,如

socketserver 和 事件Event

socketserver 处理socket服务端 # 服务端TCP: import socketserver from threading import current_thread # fork linux 下一个进程接口 windows没有这接口 # 用于处理请求的类 class MyHandler(socketserver.BaseRequestHandler): def handle(self): print(self) print(self.server) # 获取封装的服务器对象 p

windows系统调用 利用事件对象实现进程通信

1 #include "iostream" 2 #include "windows.h" 3 #include "cstring" 4 using namespace std; 5 6 static LPCTSTR g_szContinueEvent="w2kdg.EventDemo.event.Continue"; 7 8 BOOL CreateChild(){ 9 TCHAR szFilename[MAX_PATH]; 1

C#事件(event)解析

事件(event),这个词儿对于初学者来说,往往总是显得有些神秘,不易弄懂.而这些东西却往往又是编程中常用且非常重要的东西.大家都知道windows消息处理机制的重要,其实C#事件就是基于windows消息处理机制的,只是封装的更好,让开发者无须知道底层的消息处理机制,就可以开发出强大的基于事件的应用程序来. 先来看看事件编程有哪些好处. 在以往我们编写这类程序中,往往采用等待机制,为了等待某件事情的发生,需要不断地检测某些判断变量,而引入事件编程后,大大简化了这种过程: - 使用事件,可以很方

C#中的委托(Delegate)和事件(Event)

C#中的委托(Delegate)和事件(Event) 2007-11-30 11:40:00 分类: 把C#中的委托(Delegate)和事件(Event)放到现在讲是有目的的:给下次写的设计模式——观察者(Observer)有一个参考. 委托和事件应该是C#相较于C++等之前的非托管的语言提出的一个新的术语(term).“旧瓶装新酒”这样的描述似乎有些“贬义”,但确实是这样.委托也好,事件也好最初的起源是C/C++中的函数指针,关于函数指针的简单介绍可以参见我以前的一篇<C/C++中指向函数的