博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程间通信之AutoResetEvent和ManualResetEvent的原理分析
阅读量:6069 次
发布时间:2019-06-20

本文共 2202 字,大约阅读时间需要 7 分钟。

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

你可能感兴趣的文章
[转]MyBatis传入多个参数的问题 - mingyue1818
查看>>
Meteor 加入账户系统
查看>>
iOS可持续化集成: Jenkins + bundler + cocoapods + shenzhen + fastlane + pgyer
查看>>
计算几位学生的平均分
查看>>
Python黑客编程2 入门demo--zip暴力破解
查看>>
必看 :大数据挖掘中易犯的11大错误
查看>>
宿主系统为Ubuntu 14,CentOS 6.5 安装VirtualBox增强工具失败:Building the OpenGL support module[FAILED]...
查看>>
MVC学习系列14--Bundling And Minification【捆绑和压缩】--翻译国外大牛的文章
查看>>
Android实战简易教程-第十枪(画廊组件Gallery有用研究)
查看>>
POJ 2965:The Pilots Brothers' refrigerator
查看>>
Principle of Computing (Python)学习笔记(7) DFS Search + Tic Tac Toe use MiniMax Stratedy
查看>>
无法启动此程序,因为计算机中丢失 api-ms-win-crt-stdio-l1-1-0.dll 解决
查看>>
java获取指定文件夹下的所有文件名
查看>>
weex 项目开发(一) weex create project 与 weex init project 的区别
查看>>
PCH简单介绍
查看>>
c#实现用SQL池(多线程),定时批量执行SQL语句
查看>>
【译】Immutable.js: Map - 5
查看>>
【移动端 Web】怎么循序渐进地开发一个移动端页面
查看>>
Python把同一个对象循环赋值给另外一个变量
查看>>
SQL优化工具SQLAdvisor使用(转)
查看>>