基础概览

多线程之信号系统命名空间

using System.Threading;

线程同步类的继承层次关系图

终止状态和非终止状态

在终止状态下,被WaitOne()阻塞的线程会逐个得到释放。如果一个线程在EventWaitHandle对象处于终止状态时调用其WaitOne()方法,无法起到阻塞线程的作用,因为线程被其WaitOne()方法阻塞后,会立即被释放掉(实际不会阻塞)。

在非终止状态下,被WaitOne()阻塞的线程会继续被阻塞。如果一个线程在EventWaitHandle对象处于非终止状态时调用其WaitOne()方法,该线程会立即被阻塞。

  • 非终止状态:WaitOne()阻塞线程
  • 终止状态:WaitOne()不阻塞线程,允许执行后续代码

注:非终止/终止状态是针对事件来说...

WaitHandle

抽象基类,等待句柄,线程安全。

// 封装等待对共享资源的独占访问的操作系统特定的对象
public abstract class WaitHandle {
public const int WaitTimeout = 258;
protected WaitHandle();
public void Dispose();
public virtual void Close();
// 阻止当前线程,直到当前System.Threading.WaitHandle(的实例)收到信号
public virtual bool WaitOne();
public virtual bool WaitAll(WaitHandle[] waitHandles, xxx);
public virtual bool WaitAny(WaitHandle[] waitHandles, xxx);
} 

EventWaitHandle

事件等待句柄,EventWaitHandle类表示一个线程同步事件,允许线程通过操作系统互发信号和等待彼此的信号达到线程同步的目的。调用其WaitOne()方法阻塞线程运行,直到得到一个通知信号(该信号由EventWaitHandle类的Set()方法发出),然后释放线程让其不再阻塞继续运行。

// 表示一个线程同步事件
public class EventWaitHandle : WaitHandle {
public EventWaitHandle(bool initialState, EventResetMode mode, xxx);
public bool Reset(); // 将事件状态设置为非终止状态,导致线程阻塞
public bool Set(); // 将事件状态设置为终止状态,允许一个或多个等待线程继续执行
public static EventWaitHandle OpenExisting(string name, xxx); // 打开一个现有的已命名同步事件
} 

模式分类

public enum EventResetMode{
AutoReset = 0, ManualReset = 1,
}

区别:EventWaitHandle对象调用WaitOne()方法、在接收到通知信号后,是否自动调用Reset()方法重置。

AutoRest:自动重置模式。(EventWaitHandle类的子类:System.Threading.AutoResetEvent类)

当终止时,EventWaitHandle对象释放一个线程后并自动重置。如果没有等待的线程,EventWaitHandle对象将保持终止状态直到有一个线程阻止,并在释放此线程后重置。

ManualRest:手动重置模式。(EventWaitHandle类的子类:System.Threading.ManualRestEvent类)

当终止时,EventWaitHandle对象释放所有等待的线程,并保持终止状态直到手动重置。

注:终止状态和非终止状态之间可以相互转换,通常初始为非终止状态。  

方法

  • ReSet()方法:将事件状态设为非终止状态,导致线程阻塞;(设置需要等待的线程阻塞,即包含WaitOne()方法的线程阻塞)
  • Set()方法:将事件状态设为终止状态,允许一个或多个等待线程继续;(发送一个信号给操作系统,让处于等待的线程从阻塞态转换为运行态,即包含WaitOne()方法的线程不再阻塞)
  • WaitOne()方法:阻塞当前线程,直到当前的等待句柄收到信号(使本线程处于阻塞态直到收到信号为止,即当其他非阻塞线程调用set()方法时再继续执行);

示例

public static void EventWaitHandleDemo()
{
// 测试ManualReset模式
EventWaitHandle ReadyEvent = new EventWaitHandle(false, EventResetMode.ManualReset, "READY");
// 测试AutoReset模式
//EventWaitHandle ReadyEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "READY"); // 新线程
Thread readyThread = new Thread((it) =>
{
Thread.Sleep(3000);
ReadyEvent.Set();
});
readyThread.Start(); if (!ReadyEvent.WaitOne(5000)){
Console.WriteLine("ready failed!");
}else{
Console.WriteLine("ready success!");
} //ReadyEvent.Reset(); // AutoReset模式会在调用WaitOne后自动调用Reset()方法 if (!ReadyEvent.WaitOne(5000)){
Console.WriteLine("ready failed again!");
}else{
Console.WriteLine("ready success again!");
}
}  

参考:多线程编程中的EventWaitHandle示例

ManualResetEvent

// 通知一个或多个正在等待的线程已发生事件
public sealed class ManualResetEvent : EventWaitHandle {
// 用一个指示是否将初始状态设置为终止的布尔值初始化ManualResetEvent类的实例
public ManualResetEvent(bool initialState);
} 

AutoResetEvent

// 通知正在等待的线程已发生事件
public sealed class AutoResetEvent : EventWaitHandle {
// 用一个指示是否将初始状态设置为终止的布尔值初始化AutoResetEvent类新实例
public AutoResetEvent(bool initialState);
}

  

参考:

C# - 多线程 之 信号系统的更多相关文章

  1. java多线程模拟停车系统

    import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent ...

  2. 【java多线程】队列系统之说说队列Queue

    转载:http://benjaminwhx.com/2018/05/05/%E8%AF%B4%E8%AF%B4%E9%98%9F%E5%88%97Queue/ 1.简介 Queue(队列):一种特殊的 ...

  3. 【java多线程】队列系统之LinkedBlockingQueue源码

    转载:https://blog.csdn.net/tonywu1992/article/details/83419448 http://benjaminwhx.com/archives/ 1.简介 上 ...

  4. python多线程-Semaphore(信号对象)

    Semaphore(value=1) Semaphore对象内部管理一个计数器,该计数器由每个acquire()调用递减,并由每个release()调用递增.计数器永远不会低于零,当acquire() ...

  5. C语言使用pthread多线程编程(windows系统)二

    我们进行多线程编程,可以有多种选择,可以使用WindowsAPI,如果你在使用GTK,也可以使用GTK实现了的线程库,如果你想让你的程序有更多的移植性你最好是选择POSIX中的Pthread函数库,我 ...

  6. C# - 多线程 之 锁系统

    lock 关键字, Monitor 监控器, using System.Threading: // 提供同步访问对象的机制. public static class Monitor { public ...

  7. 【java多线程】队列系统之DelayQueue源码

    一.延迟队列 延迟队列,底层依赖了优先级队列PriorityBlockingQueue 二.延迟队列案例 (1)延迟队列的任务 public class DelayTask implements De ...

  8. 【java多线程】队列系统之PriorityBlockingQueue源码

    一.二叉堆 如题,二叉堆是一种基础数据结构 事实上支持的操作也是挺有限的(相对于其他数据结构而言),也就插入,查询,删除这一类 对了这篇文章中讲到的堆都是二叉堆,而不是斜堆,左偏树,斐波那契堆什么的  ...

  9. 【java多线程】队列系统之LinkedBlockingDeque源码

    1.简介 上一篇我们介绍了 LinkedBlockingDeque 的兄弟篇 LinkedBlockingQueue .听名字也知道一个实现了 Queue 接口,一个实现了 Deque 接口,由于 D ...

随机推荐

  1. C#各种同步方法 lock, Monitor,Mutex, Semaphore, Interlocked, ReaderWriterLock,AutoResetEvent, ManualResetEvent

    看下组织结构: System.Object System.MarshalByRefObject System.Threading.WaitHandle System.Threading.Mutex S ...

  2. Struts2日期类型转换

    针对日期类java.util.Date进行类型转换,要求客户端使用"yyyy-MM-dd","yyyy/MM/dd"中的任意一种输入,并以"yyyy- ...

  3. 转: 解决Github访问超慢问题

    转自:http://zengrong.net/post/2092.htm 解决Github访问超慢问题 Github is so slowly. 这段时间访问 github 都非常慢,google了一 ...

  4. .NET面试题系列[5] - 垃圾回收:概念与策略

    面试出现频率:经常出现,但通常不会问的十分深入.通常来说,看完我这篇文章就足够应付面试了.面试时主要考察垃圾回收的基本概念,标记-压缩算法,以及对于微软的垃圾回收模板的理解.知道什么时候需要继承IDi ...

  5. Asp.Net 5 新增公告仓库

    一直以来Asp.Net 5 都没有一个比较统一的公告页,对于一个在日夜更新的项目来说,很多人经常会遇到问题但是不知道去哪里寻找帮助,现在Asp.Net 5 项目组新增了一个公告仓库来解决这个问题.  ...

  6. 关于领域驱动设计(DDD)中聚合设计的一些思考

    关于DDD的理论知识总结,可参考这篇文章. DDD社区官网上一篇关于聚合设计的几个原则的简单讨论: 文章地址:http://dddcommunity.org/library/vernon_2011/, ...

  7. 《Effective java》-----读书笔记

    2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己!预计在2016年要看12本书,主要涉及java基础.Spring研究.java并 ...

  8. 提高(Android)开发效率的工具与网站

    Dev_Tools 写这篇不是为了"水",是因为有些工具确实不错,但是换个电脑要找到或者在某个时候你想用但是你只知道存在了书签里.然后就只能下载chrome然后登录账户同步书签了. ...

  9. Swift -- 对AFN框架的封装

    Swift -- 对AFN框架的封装 一.封装AFN的目的 简单的说: 解耦 日常工作中,我们一般都不会去直接使用AFNetWorking来直接发送网络请求,因为耦合性太强,假设有多个控制器都使用AF ...

  10. MySQL基础笔记

    一.登录参数 -D 打开指定数据库 -h 服务器名称 -p 密码 -P 端口 -u 用户名 -V 输出版本信息并退出 --prompt 提示符 mysql> ,或者登陆后 用prompt命令 提 ...