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 ...
随机推荐
- [C#] C# 知识回顾 - 特性 Attribute
C# 知识回顾 - 特性 Attribute [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5911289.html 目录 特性简介 使用特性 特性 ...
- 我这么玩Web Api(一):帮助页面或用户手册(Microsoft and Swashbuckle Help Page)
前言 你需要为客户编写Api调用手册?你需要测试你的Api接口?你需要和前端进行接口对接?那么这篇文章应该可以帮到你.本文将介绍创建Web Api 帮助文档页面的两种方式,Microsoft Help ...
- JavaScript基础知识总结(四)
JavaScript语法 八.函数 函数就是完成某个功能的一组语句,函数由关键字function + 函数名 + 加一组参数定义: 函数在定义后可以被重复调用,通常将常用的功能写成一个函数,利用函数可 ...
- js callee,caller学习
原文地址:js callee,caller学习 /* * caller 返回一个对函数的引用,该函数调用了当前函数. * 如果函数是由顶层调用的,那么 caller包含的就是 null . * 如果在 ...
- 【夯实Mysql基础】MySQL性能优化的21个最佳实践 和 mysql使用索引
本文地址 分享提纲: 1.为查询缓存优化你的查询 2. EXPLAIN 你的 SELECT 查询 3. 当只要一行数据时使用 LIMIT 1 4. 为搜索字段建索引 5. 在Join表的时候使用相当类 ...
- BPM配置故事之案例3-参与者与数据自动加载
这才过了两天,阿海又来了. 阿海:公司决定改进管理方式,以后物资申请的申请人和申请部门要写具体使用人的名字和部门了. 小明:不是要让我改回去吧? 阿海:那太麻烦了,你能不能把申请人改成选择,选好人自动 ...
- 14门Linux课程,打通你Linux的任督二脉!
Linux有很多优点:安全.自主.开源--,也正是这些优点使得很多人都在学Linux. 虽说网上有大把的Linux课程资源,但是对很多小白来说网上的课程资源比较零散并不适合新手学习. 正因为此,总结了 ...
- Linux网络驱动--snull
snull是<Linux Device Drivers>中的一个网络驱动的例子.这里引用这个例子学习Linux网络驱动. 因为snull的源码,网上已经更新到适合最新内核,而我自己用的还是 ...
- 【转】 XenServer的架构
一.Dom0或者控制域 XenServer从安装上看起来像是一个Linux,所以有些同学认为XenServer就是Linux或者是Linux修改的.真实的XenServer和Linux的关系是这样的: ...
- 完成C++不能做到的事 - Visitor模式
拿着刚磨好的热咖啡,我坐在了显示器前.“美好的一天又开始了”,我想. 昨晚做完了一个非常困难的任务并送给美国同事Review,因此今天只需要根据他们提出的意见适当修改代码并提交,一周的任务就完成了.剩 ...