<一>事件

事件主要用于线程间传递消息,通过事件来控制一个线程是处于执行状态还是处于挂起状态。

事件和互斥量之间的差别:

  1. 事件主要用于协调两个或者多个线程之间的动作,使其协调一致,符合逻辑。一个线程等待某个事件的发生,另一个线程则在事件发生后产生一个信号,通知那个正在等待的线程(我的理解:线程A等待键盘输入,线程B在有键盘输入后发送一个信号给A,使得A可以执行,事件就是“键盘输入”)。
  2. 互斥量主要是为了保证在任何时刻只有一个线程在使用共享资源,线程的运行次序是随机的,有操作系统决定,因此互斥量不能使两个线程按一定的顺序执行。
  3. 互斥量有信号状态是指线程正在拥有该互斥量,无信号是指没有线程拥有这个互斥量;对事件来说,当等待的事件发生时,事件对象处于活动状态,叫有信号状态,相反的,当等待的事件没有发生时,事件对象处于无信号状态。
  4. 事件一般分为两种:手动事件和自动事件。手动事件是指当事件对象处于活动状态时它会一直处于这个状态,直到显示地将其置为无信号状态;自动事件是指当事件处于有信号状态并有一个线程接收到该事件后,事件立即变为无信号状态。

<二>与事件有关的函数

函数名 作用
CreateEvent 创建一个事件
OpenEvent 打开一个已经创建的事件
SetEvent 触发一个事件
ResetEvent 复位一个事件
PulseEvent 触发并重置一个事件
WaitForSingleObject 等待单个事件
WaitForMultipleObject 等待多个事件
#include <windows.h>
#include <process.h> /* _beginthread, _endthread */
#include <iostream>
#include <fstream>
using namespace std; HANDLE hEvent; unsigned long _stdcall MyThread1(LPVOID lpParam)
{
cout<<"Wait for event\n";
WaitForSingleObject(hEvent,INFINITE);
cout<<"Get the event\n";
return ;
} unsigned long _stdcall MyThread2(LPVOID lpParam)
{
Sleep();
cout<<"Signal the event\n";
SetEvent(hEvent);
return ;
} int main()
{
HANDLE handle1,handle2;
DWORD dw1,dw2;
hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
handle1 =CreateThread(NULL,NULL,MyThread1,NULL,NULL,&dw1);
handle2 =CreateThread(NULL,NULL,MyThread2,NULL,NULL,&dw2); Sleep(); CloseHandle(handle1);
CloseHandle(handle2);
CloseHandle(hEvent); return ;
}

再看一个难一点的例子:两个读线程,一个写线程。

#include <windows.h>
#include <process.h> /* _beginthread, _endthread */
#include <iostream>
#include <fstream>
using namespace std; HANDLE hWriteEvent;
HANDLE hReadEvent[]; int buff[]; CRITICAL_SECTION cs;
BOOL isRunning = true; unsigned long _stdcall WriteThread(LPVOID lpParam)
{
hWriteEvent = CreateEvent(NULL,TRUE,FALSE,NULL);//创建一个写事件,并处于有信号状态
int k = ;
while (isRunning)
{
if(WAIT_OBJECT_0==WaitForMultipleObjects(,hReadEvent,true,))
{
for (int i = ;i<;i++)
{
buff[i]=(i+)*k;
}
k++;
PulseEvent(hWriteEvent);
}
}
return ;
} unsigned long _stdcall ReadThread1(LPVOID lpParam)
{
hReadEvent[] = CreateEvent(NULL,FALSE,TRUE,NULL);
while (isRunning)
{
WaitForSingleObject(hWriteEvent,INFINITE);
EnterCriticalSection(&cs);
cout<<"Print from Thread #1:";
for (int i = ;i<;i++)
cout<<buff[i]<<" "; cout<<endl;
LeaveCriticalSection(&cs);
SetEvent(hReadEvent[]); }
return ;
} unsigned long _stdcall ReadThread2(LPVOID lpParam)
{
hReadEvent[] = CreateEvent(NULL,FALSE,TRUE,NULL);
while (isRunning)
{
WaitForSingleObject(hWriteEvent,INFINITE);
EnterCriticalSection(&cs);
cout<<"Print from Thread #2:";
for (int i = ;i<;i++)
cout<<buff[i]<<" "; cout<<endl;
LeaveCriticalSection(&cs);
SetEvent(hReadEvent[]); }
return ;
} unsigned long _stdcall ControlThread(LPVOID lpParam)
{
isRunning = FALSE;
return ;
} int main()
{
HANDLE handle1,handle2,handle3,handle4;
DWORD dw1,dw2,dw3,dw4;
InitializeCriticalSection(&cs); handle1 = CreateThread(NULL,,WriteThread,NULL,,&dw1);
handle2 = CreateThread(NULL,,ReadThread1,NULL,,&dw2);
handle3 = CreateThread(NULL,,ReadThread2,NULL,,&dw3);
Sleep();
handle4 = CreateThread(NULL,,ControlThread,NULL,,&dw4); CloseHandle(handle1);
CloseHandle(handle2);
CloseHandle(handle3);
CloseHandle(handle4);
CloseHandle(hWriteEvent);
CloseHandle(hReadEvent[]);
CloseHandle(hReadEvent[]); return ;
}

Windows环境下多线程编程原理与应用读书笔记(7)————事件及其应用的更多相关文章

  1. Windows环境下多线程编程原理与应用读书笔记(1)————基本概念

    自从学了操作系统知识后,我就对多线程比较感兴趣,总想让自己写一些有关多线程的程序代码,但一直以来,发现自己都没怎么好好的去全面学习这方面的知识,仅仅是完成了操作系统课程上的小程序,对多线程的理解也不是 ...

  2. Windows环境下多线程编程原理与应用读书笔记(3)————Windows环境中的多线程实现(3)

    纤程 纤程(fiber): 相当于用户级别的线程或轻进程.纤程由Win32库函数支持,对核心是不可见的.纤程可以通过SwitchToFiber显示至另一合作纤程,以实现合作纤程之间的协同.线程是在Wi ...

  3. Windows环境下多线程编程原理与应用读书笔记(8)————信号量及其应用

    <一>线程间同步原因 线程间竞争共享资源: 线程间为完成某个任务而协作: 通过互斥量可以实现线程间由于竞争所需要的同步,通过事件可以实现线程间由于协作所需要的同步. 信号量很好地将互斥量和 ...

  4. Windows环境下多线程编程原理与应用读书笔记(6)————临界段及其应用

    <一>临界段 临界段对象通过提供所有线程必须共享的对象来控制线程.只有拥有临界段对象的线程才能够访问保护的资源.在另一个线程可以访问该资源之前,前一线程必须释放临界段对象,一遍新的线程可以 ...

  5. Windows环境下多线程编程原理与应用读书笔记(5)————互斥及其应用

    <一>互斥的同步机制 思想:当一个线程获得互斥量了后,其他所有要获取同一个互斥量的线程都处于阻塞状态,直到第一个线程释放互斥量为止. 设想几个线程竞争同一个互斥量,其中一个线程获得了互斥量 ...

  6. Windows环境下多线程编程原理与应用读书笔记(2)————面向对象技术

    面向对象技术是学C++需要重点掌握的知识,因为我觉得自己的基础还是比较可以,这一章节的内容就只是粗略的读了一遍,在此就不做过多的笔记.

  7. Windows环境下多线程编程原理与应用读书笔记(4)————线程间通信概述

    <一>线程间通信方法 全局变量方式:进程中的线程共享全局变量,可以通过全局变量进行线程间通信. 参数传递法:主线程创建子线程并让子线程为其服务,因此主线程和其他线程可以通过参数传递进行通信 ...

  8. Java多线程编程实战指南 设计模式 读书笔记

    线程设计模式在按其有助于解决的多线程编程相关的问题可粗略分类如下. 不使用锁的情况下保证线程安全: Immutable Object(不可变对象)模式.Thread Specific Storage( ...

  9. 关于docker在windows环境下运行的第一次体验

    关于docker在windows环境下执行的原理 1.1.           首先是Docker Quickstart启动,如果在虚拟机Oracle VM VirtualBox不存在default虚 ...

随机推荐

  1. Markdown使用简单示例

    标题示例: 标题一 #标题一 标题二 #标题二 标题三 ###标题三 标题四 ####标题四 标题五 #####标题五 标题六 ######标题六 连接示例 [![License](图片地址)](跳转 ...

  2. 国外支付PayPal

    PayPal官网https://www.paypal.com/ PayPal沙箱https://www.sandbox.paypal.com/signin?country.x=US&local ...

  3. poj1067威佐夫博奕

    取石子游戏 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 31490   Accepted: 10374 Descripti ...

  4. C++PrimerPlus第6版 第四章——复合类型

    1,复合类型主要包含:数组.结构.联合.枚举.类.指针.引用等. 2,数组.长度必须确定.即编译阶段,数组的长度就得确定好.所以只能使用常量(#define.const)声明数组长度.如果使用变量声明 ...

  5. fitnesse - Variables and Symbols

    fitnesse - Variables and Symbols 2017-09-30 目录 1 Variables(静态变量)  1.1 定义及使用  1.2 Variable作用域    1.2. ...

  6. install xdebug

    安装准备 安排php的xdebug扩展,在php.ini上配置xdebug.通过phpinfo或者php-m 查看 [Xdebug] zend_extension ="D:\upupw7\P ...

  7. ZOJ2185 简单分块 找规律

    初步找大概位置,然后找精确位置,算是简单化的分块吧! #include<cstdio> #include<cstdlib> #include<iostream> u ...

  8. WebService文件上传相关配置(404.13、超出限制、超时)

    最近在做文件上传的功能,遇到一些问题,记录如下,以备以后使用. 1.HTTP Error 404.13 - Not Found,请求筛选模块被配置为拒绝超过请求内容长度的请求. IIS默认允许请求长度 ...

  9. 从头编写 asp.net core 2.0 web api 基础框架 (5) EF CRUD

    第1部分:http://www.cnblogs.com/cgzl/p/7637250.html 第2部分:http://www.cnblogs.com/cgzl/p/7640077.html 第3部分 ...

  10. 将 C# 枚举反序列化为 JSON 字符串 基础理论

    该转换过程需要引用 Newtonsoft.JSON,这其中的转换过程还是蛮有意思的. 一.定义枚举 /// <summary> /// 托寄物品枚举 /// </summary> ...