基础概览

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

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. 来吧,HTML5之基础标签(下)

    <dialog> 标签 定义对话框或窗口. <dialog> 标签是 HTML 5 的新标签.目前只有 Chrome 和 Safari 6 支持 <dialog>  ...

  2. Oracle手边常用70则脚本知识汇总

    Oracle手边常用70则脚本知识汇总 作者:白宁超 时间:2016年3月4日13:58:36 摘要: 日常使用oracle数据库过程中,常用脚本命令莫不是用户和密码.表空间.多表联合.执行语句等常规 ...

  3. C# 给word文档添加水印

    和PDF一样,在word中,水印也分为图片水印和文本水印,给文档添加图片水印可以使文档变得更为美观,更具有吸引力.文本水印则可以保护文档,提醒别人该文档是受版权保护的,不能随意抄袭.前面我分享了如何给 ...

  4. java设计模式之单例模式(几种写法及比较)

    概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...

  5. JavaScript将字符串中的每一个单词的第一个字母变为大写其余均为小写

    要求: 确保字符串的每个单词首字母都大写,其余部分小写. 这里我自己写了两种方法,或者说是一种方法,另一个是该方法的变种. 第一种: function titleCase(str) { var new ...

  6. 从史上八大MySQL事故中学到的经验

    本文列举了史上八大MySQL宕机事件原因.影响以及人们从中学到的经验,文中用地震级数来类比宕机事件的严重性和后果,排在最严重层级前两位的是由于亚马逊AWS宕机故障(相当于地震十级和九级). 一.Per ...

  7. 记录在Windows上安装和使用Oracle数据库过程中的坑

    1.安装Oracle Oracle软件是免费的,可以去官网下载相应的安装包.但是如果用于商业用途需要购买License.官网上针对各种平台,32位和64位都有,如果在Windows一般会下载到两个文件 ...

  8. 一步步搭建自己的博客 .NET版(2、评论功能)

    前言 这次开发的博客主要功能或特点:    第一:可以兼容各终端,特别是手机端.    第二:到时会用到大量html5,炫啊.    第三:导入博客园的精华文章,并做分类.(不要封我)    第四:做 ...

  9. 【腾讯Bugly干货分享】一步一步实现Android的MVP框架

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5799d7844bef22a823b3ad44 内容大纲: Android 开发 ...

  10. Windows平台分布式架构实践 - 负载均衡(下)

    概述 我们在上一篇Windows平台分布式架构实践 - 负载均衡中讨论了Windows平台下通过NLB(Network Load Balancer) 来实现网站的负载均衡,并且通过压力测试演示了它的效 ...