C# - 多线程 之 信号系统
基础概览
多线程之信号系统命名空间
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!");
}
}
ManualResetEvent
// 通知一个或多个正在等待的线程已发生事件
public sealed class ManualResetEvent : EventWaitHandle {
// 用一个指示是否将初始状态设置为终止的布尔值初始化ManualResetEvent类的实例
public ManualResetEvent(bool initialState);
}
AutoResetEvent
// 通知正在等待的线程已发生事件
public sealed class AutoResetEvent : EventWaitHandle {
// 用一个指示是否将初始状态设置为终止的布尔值初始化AutoResetEvent类新实例
public AutoResetEvent(bool initialState);
}
参考:
- ;
C# - 多线程 之 信号系统的更多相关文章
- java多线程模拟停车系统
import java.util.Random; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent ...
- 【java多线程】队列系统之说说队列Queue
转载:http://benjaminwhx.com/2018/05/05/%E8%AF%B4%E8%AF%B4%E9%98%9F%E5%88%97Queue/ 1.简介 Queue(队列):一种特殊的 ...
- 【java多线程】队列系统之LinkedBlockingQueue源码
转载:https://blog.csdn.net/tonywu1992/article/details/83419448 http://benjaminwhx.com/archives/ 1.简介 上 ...
- python多线程-Semaphore(信号对象)
Semaphore(value=1) Semaphore对象内部管理一个计数器,该计数器由每个acquire()调用递减,并由每个release()调用递增.计数器永远不会低于零,当acquire() ...
- C语言使用pthread多线程编程(windows系统)二
我们进行多线程编程,可以有多种选择,可以使用WindowsAPI,如果你在使用GTK,也可以使用GTK实现了的线程库,如果你想让你的程序有更多的移植性你最好是选择POSIX中的Pthread函数库,我 ...
- C# - 多线程 之 锁系统
lock 关键字, Monitor 监控器, using System.Threading: // 提供同步访问对象的机制. public static class Monitor { public ...
- 【java多线程】队列系统之DelayQueue源码
一.延迟队列 延迟队列,底层依赖了优先级队列PriorityBlockingQueue 二.延迟队列案例 (1)延迟队列的任务 public class DelayTask implements De ...
- 【java多线程】队列系统之PriorityBlockingQueue源码
一.二叉堆 如题,二叉堆是一种基础数据结构 事实上支持的操作也是挺有限的(相对于其他数据结构而言),也就插入,查询,删除这一类 对了这篇文章中讲到的堆都是二叉堆,而不是斜堆,左偏树,斐波那契堆什么的 ...
- 【java多线程】队列系统之LinkedBlockingDeque源码
1.简介 上一篇我们介绍了 LinkedBlockingDeque 的兄弟篇 LinkedBlockingQueue .听名字也知道一个实现了 Queue 接口,一个实现了 Deque 接口,由于 D ...
随机推荐
- 套用JQuery EasyUI列表显示数据、分页、查询
声明,本博客从csdn搬到cnblogs博客园了,以前的csdn不再更新,朋友们可以到这儿来找我的文章,更多的文章会发表,谢谢关注! 有时候闲的无聊,看到extjs那么肥大,真想把自己的项目改了,最近 ...
- 9、委托、事件、Lambda
开始 关于委托,肯定是要有问题的. 第一个问题,委托用来干什么? 看.net中的表述:在.net平台下,委托类型用来定义和相应应用程序中的回调.(回调?处理内存中两个实体双向通信的一种技术.) 第 ...
- RIFF和WAVE音频文件格式
RIFF file format RIFF全称为资源互换文件格式(Resources Interchange File Format),是Windows下大部分多媒体文件遵循的一种文件结构.RIFF文 ...
- ASP.NET Core 中文文档 第四章 MVC(3.9)视图组件
作者: Rick Anderson 翻译: 娄宇(Lyrics) 校对: 高嵩 章节: 介绍视图组件 创建视图组件 调用视图组件 演练:创建一个简单的视图组件 附加的资源 查看或下载示例代码 介绍视图 ...
- c# 基础 object ,new操作符,类型转换
参考页面: http://www.yuanjiaocheng.net/webapi/config-webapi.html http://www.yuanjiaocheng.net/webapi/web ...
- Nexus(一)环境搭建
昨天,成功搭建了自己的 Maven 环境(详见:Maven(一)环境搭建),今天就来研究和探讨下 Nexus 的搭建! 使用背景: 安装环境:Windows 10 -64位 JDK版本:1.7 Mav ...
- 新手学习web遇到的一些乱码问题
在新手学习web网站学习的时候经常会遇到?????这种乱码,对于刚起步的菜鸟来说真的很头痛,很容易打击继续学的信心当然了对于菜鸟的我最近也遇到过乱码问题,沉浸其中不能自拔,爱的深啊!!!!!我所遇到的 ...
- ES6(块级作用域)
我们都知道在javascript里是没有块级作用域的,而ES6添加了块级作用域,块级作用域能带来什么好处呢?为什么会添加这个功能呢?那就得了解ES5没有块级作用域时出现了哪些问题. ES5在没有块级作 ...
- SpringMVC视图解析器
SpringMVC视图解析器 前言 在前一篇博客中讲了SpringMVC的Controller控制器,在这篇博客中将接着介绍一下SpringMVC视 图解析器.当我们对SpringMVC控制的资源发起 ...
- 解决Ubuntu Kylin 1610安装ANSYS17.2的NVIDIA显卡驱动问题
Ubuntu Kylin 1610在安装完毕后,会自动安装显卡驱动,对于一般的图形图像使用来说自然不会有太大的问题,但是对于ANSYS17.2的一些模块,还是会出现问题.一个比较常见的问题就是Open ...