基础概览

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

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. ASP.NET Core 中文文档 第四章 MVC(4.3)过滤器

    原文:Filters 作者:Steve Smith 翻译:刘怡(AlexLEWIS) 校对:何镇汐 ASP.NET MVC 过滤器 可在执行管道的前后特定阶段执行代码.过滤器可以配置为全局有效.仅对控 ...

  2. JVM类加载

    JVM的类加载机制就是:JVM把描述类的class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被JVM直接使用的Java类型 ClassLoader JVM中的ClassLoade ...

  3. 微服务与Docker介绍

    什么是微服务 微服务应用的一个最大的优点是,它们往往比传统的应用程序更有效地利用计算资源.这是因为它们通过扩展组件来处理功能瓶颈问题.这样一来,开发人员只需要为额外的组件部署计算资源,而不需要部署一个 ...

  4. Android中的LinearLayout布局

    LinearLayout : 线性布局 在一般情况下,当有很多控件需要在一个界面列出来时,我们就可以使用线性布局(LinearLayout)了,  线性布局是按照垂直方向(vertical)或水平方向 ...

  5. Kotlin与Android SDK 集成(KAD 05)

    作者:Antonio Leiva 时间:Dec 19, 2016 原文链接:https://antonioleiva.com/kotlin-integrations-android-sdk/ 使用Ko ...

  6. Linux实战教学笔记02:计算机系统硬件核心知识

    标签(空格分隔):Linux实战教学笔记-陈思齐 第1章 互联网企业常见服务器介绍 1.1 互联网公司服务器品牌 - DELL(大多数公司,常用) - HP - IBM(百度在用) 浪潮 联想 航天联 ...

  7. Linux环境下常见漏洞利用技术(培训ppt+实例+exp)

    记得以前在drops写过一篇文章叫 linux常见漏洞利用技术实践 ,现在还可以找得到(https://woo.49.gs/static/drops/binary-6521.html), 不过当时开始 ...

  8. date命令

    GNU的date提供+%s(小写s), 能打印出自1970-01-01 00:00:00到当前时间的秒数. 这可能大家都不陌生,但有两点需要注意: 1. %s存在于GNU扩展版本.像在solaris等 ...

  9. 用IntelliJ IDEA创建Gradle项目简单入门

    Gradle和Maven一样,是Java用得最多的构建工具之一,在Maven之前,解决jar包引用的问题真是令人抓狂,有了Maven后日子就好过起来了,而现在又有了Gradle,Maven有的功能它都 ...

  10. 【Java并发编程实战】-----“J.U.C”:CLH队列锁

    在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...