多线程间通信之AutoResetEvent和ManualResetEvent的原理分析
AutoResetEvent
允许线程通过发信号互相通信。 通常,当线程需要独占访问资源时使用该类。
线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。 如果 AutoResetEvent 为非终止状态,则线程会被阻止,并等待当前控制资源的线程通过调用 Set 来通知资源可用。
调用 Set 向 AutoResetEvent 发信号以释放等待线程。 AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。 如果没有任何线程在等待,则状态将无限期地保持为终止状态。
如果当 AutoResetEvent 为终止状态时线程调用 WaitOne,则线程不会被阻止。 AutoResetEvent 将立即释放线程并返回到非终止状态。
----------------------------------------------------------------------------------
ManualResetEvent
允许线程通过发信号互相通信。 通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。
当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态。 此线程可被视为控制 ManualResetEvent。 调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。 当控制线程完成活动时,它调用Set 以发出等待线程可以继续进行的信号。 并释放所有等待线程。
一旦它被终止,ManualResetEvent 将保持终止状态,直到它被手动重置。 即对 WaitOne 的调用将立即返回。
可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false。
ManualResetEvent 也可以同 staticWaitAll 和 WaitAny 方法一起使用。
----------------------------------------------------------------------------------
生活中的例子
AutoResetEvent :在上海坐地铁,检票口有个刷卡的通道,一次只能一个人刷卡后通过,而我过后,它又是关闭的,另一个人又得再刷卡.一次操作,只有一个事件,这时就是非终止状态,一般是用来同步访问资源.
ManualResetEvent :公司园区的大门很大,一次可以多人通过。
----------------------------------------------------------------------------------
ManualResetEvent和AutoResetEvent 比较
ManualResetEvent和AutoResetEvent都继承自EventWaitHandler,它们的唯一区别就在于父类 EventWaitHandler的构造函数参数EventResetMode不同,这样我们只要弄清了参数EventResetMode值不同时,EventWaitHandler类控制线程同步的行为有什么不同,两个子类也就清楚了。
共同点:
A、Set方法将事件状态设置为终止状态,允许一个或多个等待线程继续;Reset方法将事件状态设置为非终止状态,导致线程阻止;WaitOne阻止当前线程,直到当前线程的WaitHandler收到事件信号。
B、可以通过构造函数的参数值来决定其初始状态,若为true则事件为终止状态从而使线程为非阻塞状态,为false则线程为阻塞状态。
C、如果某个线程调用WaitOne方法,则当事件状态为终止状态时,该线程会得到信号,继续向下执行。
不同点:
A、AutoResetEvent.WaitOne()每次只允许一个线程进入,当某个线程得到信号后,AutoResetEvent会自动又将信号置为不发送状态,则其他调用WaitOne的线程只有继续等待,也就是说AutoResetEvent一次只唤醒一个线程;
B、ManualResetEvent则可以唤醒多个线程,因为当某个线程调用了ManualResetEvent.Set()方法后,其他调用WaitOne的线程获得信号得以继续执行,而ManualResetEvent不会自动将信号置为不发送。
C、也就是说,除非手工调用了ManualResetEvent.Reset()方法,则ManualResetEvent将一直保持有信号状态,ManualResetEvent也就可以同时唤醒多个线程继续执行。
---------------------------------------------------------------------------------
限制同一台电脑中同时打开两个相同的程序。具体实现可以参考《用Mutex或进程限制用户在一台电脑上同时打开两个程序》。
转载于:https://www.cnblogs.com/lichengcai/p/AutoResetEvent_ManualResetEvent.html
多线程间通信之AutoResetEvent和ManualResetEvent的原理分析相关推荐
- 单线程间通信 多线程间通信
单线程间通信 首先实现一个EventQueue,该Queue有如下三种状态: ·队列满--最多可容纳多少个Event,好比一个系统最多同时能够受理多少业务一样: ·队列空--当所有的Event都被处理 ...
- 【SemiDrive源码分析】【MailBox核间通信】46 - Android侧 RPMSG_IPCC_RPC驱动分析(下) 之 RPMSG_IPCC_RPC驱动初始化、数据收发流程分析
[SemiDrive源码分析][MailBox核间通信]46 - Android侧 RPMSG_IPCC_RPC驱动分析(下) 之 RPMSG_IPCC_RPC驱动初始化.数据收发流程分析 三. rp ...
- 【SemiDrive源码分析】【MailBox核间通信】45 - Android侧 RPMSG_IPCC_RPC驱动分析(上) 之 RPMSG设备 与 RPMSG驱动 匹配过程分析
[SemiDrive源码分析][MailBox核间通信]45 - Android侧 RPMSG_IPCC_RPC驱动分析(上) 之 RPMSG设备 与 RPMSG驱动 匹配过程分析 一. IPCC_R ...
- MFC VC++多线程间通信
线程间的通信 1.线程之间的通信简介 一般而言,在一个应用程序中(即进程),一个线程往往不是孤立存在的,常常需要和其它线程通信,以执行特定的任务.如主线程和次线程,次线程与次线程,工作线程和用户界面线 ...
- Linux多线程间通信和多进程间通信的方式
文章目录 一.进程间的通信方式 1. 进程间通信的概念 1.1. 进程通信的目的: 1.2. Linux 进程间通信(IPC)的发展 2. 进程间通信的7种方式 2.1. 管道/匿名管道(pipe) ...
- MFC 多线程间通信
AfxBeginThead 全局变量 参数传递 消息传递 线程通信 目录(?)[-] 线程间的通信 线程之间的通信简介 全局变量方式 参数传递方式 消息传递方式 线程同步法 线程间的通信 1.线 ...
- android 多线程间通信,android实现线程间通信的四种常见方式
1,通过Handler机制 主线程中定义Handler,子线程发消息,通知Handler完成UI更新,Handler对象必须定义在主线程中,如果是多个类直接互相调用,就不是很方便,需要传递conten ...
- (十一)boost库之多线程间通信
1.互斥锁 在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性.每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象. # ...
- wxpython多线程消息传递_wxpython多线程间通信
#!bin/bash/python#-*- coding=utf-8 -*- importtimeimportwxfrom threading importThreadfrom wx.lib.pubs ...
最新文章
- BigDecimal使用时的参数详解
- mongodb连接失败_MongoDB 基础入门
- 如何“漂亮”地解决dota类游戏网络延迟同步?
- 如何用Python发送通知到微信?
- Docker教程(一) Docker入门教程
- Quartz.NET快速入门指南
- 云端之战:Thomas Kurian离职,Java 11趋向收费,Ellison豪赌ERP和云数据库
- 【已解决】格式化SD卡提示“这张磁盘有写保护”,试过将SD开关拨向两边,均失败。
- c语言 修正正弦曲线,[原创]正弦曲线
- 2017ICPCECIC MJF wants to work
- 【12月26日】A股滚动市盈率PE最低排名
- 胡子决定编程语言运势[转载]
- 途家木鸟美团夏日折扣对垒,门槛低就一定香吗?
- php如何打开excel文件,如何使用php获取excel文件数据
- KaTex 数学公式 基础
- 利用linux BT5来破解无线 破解无线
- mina java c_Mina简介
- PMP证书含金量如何高?
- 用八爪鱼获取微博社区管理中心的举报文本
- echarts柱状图上增加icon图标