Event是内核对象,他可以分为自动和手动两种模式。

HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCTSTR lpName
);
参数
lpEventAttributes 安全属性。NULL 表示使用默认属性。该属性在
Windows 95中会被忽略。
bManualReset 如为FALSE,表示这个event 将在变成激发状态
(因而唤醒一个线程)之后,自动重置(reset)为
非激发状态。如果是TRUE,表示不会自动重置,
必须靠程序操作(调用ResetEvent())才能将激发
状态的event 重置为非激发状态。
bInitialState 如为TRUE,表示这个event 一开始处于激发状
态。如为FALSE,则表示这个event 一开始处于
非激发状态。
lpNameEvent 对象的名称。任何线程或进程都可以根据这
个文字名称,使用这一event 对象。
SetEvent()  把event  对象设为激发状态
ResetEvent() 把event 对象设为非激发状态(译注:在此我要提醒读者,
"Reset" 的意思是“设定为非激发状态”,而非“重新设定为
激发状态”。)
PulseEvent() 如果是一个 Manual Reset Event :把event 对象设为激发状
态,唤醒“所有”等待中的线程,然后event 恢复为非激发
状态。如果是一个Auto Reset Event:把event 对象设为激
发状态,唤醒“一个”等待中的线程,然后event 恢复为非
激发状态

下面做一个模拟实验,用两个线程轮流输出10次,当然哪个先开始也是可以控制的。

#pragma once
#include <Windows.h>
#include <iostream> using namespace std; class EventOption
{
public:
EventOption(void);
~EventOption(void);
void StartRnner();
void ReleaseOption();
private:
static DWORD WINAPI ThreadFunctionA(LPVOID param);
static DWORD WINAPI ThreadFunctionB(LPVOID param);
void FunctionA();
void FunctionB();
private:
HANDLE m_hThreadA;
HANDLE m_hThreadB;
HANDLE m_hEventA;
HANDLE m_hEventB;
}; #include "EventOption.h" EventOption::EventOption(void)
{
} EventOption::~EventOption(void)
{
}
// interface
void EventOption::StartRnner()
{
m_hEventA = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hEventB = CreateEvent(NULL, TRUE, FALSE, NULL);
SetEvent(m_hEventA);
m_hThreadA = CreateThread(NULL, , ThreadFunctionA, this, , NULL);
m_hThreadB = CreateThread(NULL, , ThreadFunctionB, this, , NULL);
} void EventOption::ReleaseOption()
{
WaitForSingleObject(m_hThreadA, INFINITE);
WaitForSingleObject(m_hThreadB, INFINITE);
CloseHandle(m_hEventA);
CloseHandle(m_hEventB);
CloseHandle(m_hThreadA);
CloseHandle(m_hThreadB);
}
//private
DWORD EventOption::ThreadFunctionA(LPVOID param)
{
EventOption *pThis = (EventOption*)param;
pThis->FunctionA();
return ;
}
DWORD EventOption::ThreadFunctionB(LPVOID param)
{
EventOption *pThis = (EventOption*)param;
pThis->FunctionB();
return ;
} void EventOption::FunctionA()
{
int iCount = ;
while(iCount--)
{
WaitForSingleObject(m_hEventA, INFINITE);
cout<<"FunctionA: "<<iCount<<endl;
ResetEvent(m_hEventA);
SetEvent(m_hEventB);
}
} void EventOption::FunctionB()
{
int iCount = ;
while(iCount--)
{
WaitForSingleObject(m_hEventB, INFINITE);
cout<<"FunctionB: "<<iCount<<endl;
ResetEvent(m_hEventB);
SetEvent(m_hEventA);
}
} #include "EventOption.h"
int _tmain(int argc, _TCHAR* argv[])
{
EventOption test;
test.StartRnner();
test.ReleaseOption();
::getchar();
return ;
}

win32 多线程 (五)Event的更多相关文章

  1. Win32多线程编程(3) — 线程同步与通信

      一.线程间数据通信 系统从进程的地址空间中分配内存给线程栈使用.新线程与创建它的线程在相同的进程上下文中运行.因此,新线程可以访问进程内核对象的所有句柄.进程中的所有内存以及同一个进程中其他所有线 ...

  2. 深入浅出Win32多线程程序设计之基本概念

    一.深入浅出Win32多线程程序设计之基本概念[转] 引言 从单进程单线程到多进程多线程是操作系统发展的一种必然趋势,当年的DOS系统属于单任务操作系统,最优秀的程序员也只能通过驻留内存的方式实现所谓 ...

  3. win32多线程-异步过程调用(asynchronous Procedure Calls, APCs)

    使用overlapped I/O并搭配event对象-----win32多线程-异步(asynchronous) I/O事例,会产生两个基础性问题. 第一个问题是,使用WaitForMultipleO ...

  4. win32多线程-异步(asynchronous) I/O

    I/O设备是个慢速设备,无论打印机.调制解调器,甚至硬盘,与CPU相比都奇慢无比,坐下来干等I/O的完成是一件不甚明智事情. 异步(asynchronous) I/O在win32多线程程序设计中被称为 ...

  5. 多线程学习:win32多线程编程基本概念(转)

    一.定义: 1.进程和线程的区别 进程:是程序的执行过程,具有动态性,即运行的程序就叫进程,不运行就叫程序 ,每个进程包含一到多个线程.线程:系统中的最小执行单元,同一进程中有多个线程,线程可以共享资 ...

  6. win32多线程: 线程创建与结束等待

    #include<Windows.h> #include<iostream> using namespace std; /*1.在启动一个线程之前,必须为线程编写一个全局的线程 ...

  7. 由《win32多线程程序设计》临界区的问题所想

    之前看侯捷翻译的<win32多线程程序设计>中关于线程同步中的临界区问题,其中举得例子是对链表的操作.死锁的问题是对一个Swaplist函数的问题,现列举代码如下: void SwapLi ...

  8. Win32多线程编程(1) — 基础概念篇

      内核对象的基本概念 Windows系统是非开源的,它提供给我们的接口是用户模式的,即User-Mode API.当我们调用某个API时,需要从用户模式切换到内核模式的I/O System Serv ...

  9. Win32 多线程的创建方法和基本使用

    Win32多线程的创建方法主要有: (1)CreateThread() (2)_beginthread()&&_beginthreadex() (3)AfxBeginThread() ...

  10. win32多线程-重写消息循环

    最近正在学习<win32多线程程序设计>,这是其中一段重写消息循环的代码事例,以后可能用的上. while (!quit || gNumPrinting > 0) { // Wait ...

随机推荐

  1. bzoj 2770 YY的Treap

    Written with StackEdit. Description 志向远大的\(YY\)小朋友在学完快速排序之后决定学习平衡树,左思右想再加上\(SY\)的教唆,\(YY\)决定学习\(Trea ...

  2. The last packet sent successfully to the server was 0 milliseconds ago

    出现异常”The last packet sent successfully to the server was 0 milliseconds ago.“的大部分原因是由于数据库回收了连接,而系统的缓 ...

  3. 【学习笔记】Manacher算法

    本文部分图片来源 代码来源(代码是学姐哒.. 一.引入 Manacher算法是用来求最长回文子串的算法,时间复杂度O(n). 回文子串指的是''aacaa'',''noon'',这种正着反着读都一样的 ...

  4. IE兼容模式与非兼容模式下jq的写法

    1.  $("#LabelRepeatType").removeAttr("disabled");                $("#LabelF ...

  5. 常用JavaScript操作页面元素的方法

    1.取得dropdownlist的选中值 var ddl =document.getElementById('<%=ddlusers.ClientID%>'); var index = d ...

  6. golang动态调用方法

    package main import ( "fmt" "reflect" ) type YourT1 struct { } func (y *YourT1) ...

  7. java代码求输入数的平均值~~~~

    总结:1.谢谢程老师,一个很好的老师,人很普通,但是浑浊的世界里,那一份真实感动到底~~~~很感谢他 2.这里注意两个方面,也是我最大的弱点:循环和数组的length属性.前者运用不灵活,后者自己总是 ...

  8. SpringBoot中通过SpringBootServletInitializer如何实现容器初始化

    相关文章 <Servlet3.0之四:动态注册和Servlet容器初始化> <SpringBoot中通过SpringBootServletInitializer如何实现组件加载> ...

  9. HUSTOJ 昆虫繁殖(递推)

    昆虫繁殖 时间限制: 1 Sec  内存限制: 128 MB提交: 25  解决: 16[提交][状态][讨论版][命题人:quanxing] 题目描述 科学家在热带森林中发现了一种特殊的昆虫,这种昆 ...

  10. thinkphp遇到的小问题,js文件中U方法不被解析

    我想在js文件中写ajax, 写完发现异常, 本以为是js文件中不支持ajax 后来发现时地址解析错误. 也就是U方法在js文件中不被解析. 貌似thinkphp解析,tpl文件中的一些元素. js文 ...