前面说的互斥量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;
}

运行结果如下所示:

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

  1. windows多线程同步--事件

    推荐参考博客:秒杀多线程第六篇 经典线程同步 事件Event   事件是内核对象,多用于线程间通信,可以跨进程同步 事件主要用到三个函数:CreateEvent,OpenEvent,SetEvent, ...

  2. 多线程相关------事件Event

    Event可以实现不同进程中的线程同步. 相关函数: CreateEvent创建或打开一个事件对象 HANDLE WINAPI CreateEvent( _In_opt_ LPSECURITY_ATT ...

  3. 总结windows多线程同步互斥

    windows多线程同步互斥--总结 我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同 ...

  4. windows多线程同步互斥--总结

    我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同步--临界区 windows多线程同步 ...

  5. {Python之线程} 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Threading模块 九 锁 十 信号量 十一 事件Event 十二 条件Condition(了解) 十三 定时器

    Python之线程 线程 本节目录 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Thr ...

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

    原文地址:http://blog.csdn.net/morewindows/article/details/7445233 上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的“线程所有权” ...

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

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇 一个经典的多线程同步问题> <秒杀多线程第五篇 经典线程同步关键段CS> 上一篇中使用关键段来解决经典的多线程同步互斥问题 ...

  8. 多线程面试题系列(6):经典线程同步 事件Event

    上一篇中使用关键段来解决经典的多线程同步互斥问题,由于关键段的"线程所有权"特性所以关键段只能用于线程的互斥而不能用于同步.本篇介绍用事件Event来尝试解决这个线程同步问题.首先 ...

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

    完整的程序在下载:http://download.csdn.net/detail/dijkstar/7913249 用户层创建的事件Event是一个Handle句柄,和内核中的创建的内核模式下的KEV ...

  10. 并发编程~~~多线程~~~线程queue, 事件event,

    一 线程queue 多线程抢占资源,只能让其串行. 互斥锁 队列 import queue q = queue.Queue() # 先进先出 q = queue.LifoQueue() # 先进后出 ...

随机推荐

  1. 洛咕 P2468 [SDOI2010]粟粟的书架

    强行二合一啊... 前面直接二分最小值,二维前缀和.后面用主席树查最小值.注意要写\(nlogn\). // luogu-judger-enable-o2 #include<bits/stdc+ ...

  2. [Luogu1891]疯狂LCM[辗转相减法]

    题意 多组询问,每次给定 \(n\) ,求:\(\sum_{i=1}^nlcm(i,n)\) . \(\rm T \leq 3\times 10^4\ ,n \leq 10^6\). 分析 推式子: ...

  3. MySQLConnector/ODBC 安装时遇到的小问题

    今天在新做的 Win2008R2 上想使用 SqlDbx 管理 MySQL,提示需要安装 MySQLConnector/ODBC,这没什么,以前装过的,按要求下载安装一个就是了. 结果在安装 MySQ ...

  4. (转载)jQuery判断checkbox是否选中的3种方法(个人用第二种方法)

    方法一: if ($("#checkbox-id")get(0).checked) {     // do something } 方法二: if($('#checkbox-id' ...

  5. Rmdir方法

    删除现有目录或文件夹. 语法 RmDir路径 所需的_路径_参数标识的目录或文件夹要移除的字符串表达式. _路径_可以包含驱动器. 如果没有指定驱动器, RmDir 将删除当前驱动器上的目录或文件夹. ...

  6. python中@property和property函数使用

    1.基本的@property使用,可以把函数当做属性用 class Person(object): @property def get_name(self): print('我叫xxx') def m ...

  7. [WPF]解决模板中ContextMenu绑定CommandParameter的问题

    直接上代码,首先是一个ContextMenu的模板: <ContextMenu x:Key="Menu" BorderThickness="0.3" Fo ...

  8. [学习笔记]PCL使用心得

    最近开始做研究生毕设,有一部分因为没有什么好的思路,就把以前用过的PCL点云搬出来,重新用源码装了一遍PCL,一开始装的过程中没什么大问题,在后面用的时候碰到了很多小问题,特此记录. 1.PCL版本问 ...

  9. 【LeetCode算法题库】Day4:Regular Expression Matching & Container With Most Water & Integer to Roman

    [Q10] Given an input string (s) and a pattern (p), implement regular expression matching with suppor ...

  10. eclipse检出SVN代码的详细流程

    1.添加SVN资源库位置(未安装SVN,请先安装SVN) 2.因为该项目不是maven项目 所以还需要加入jar包(将项目lib里面的jar都Buile Path) 3.我这个项目需要修改编码格式 右 ...