关于C#中Monitor的wait/pulse的理解

wait:表示释放对象上的锁并阻止当前线程,直到它重新获取该锁。

pulse:表示通知等待队列中的线程锁定对象状态的更改。

当线程调用 Wait 时,它会释放对象上的锁并进入对象的等待队列。 对象的就绪队列中的下一个线程 (如果有一个) 获取锁并独占使用该对象。 调用 Wait 的所有线程都保留在等待队列中,直到它们收到来自 Pulse 或 PulseAll 的信号,由锁的所有者发送。 如果 Pulse 发送 ,则只会影响等待队列头部的线程。 如果 PulseAll 发送 ,则等待对象的所有线程都会受到影响。 收到信号后,一个或多个线程离开等待队列并进入就绪队列。 允许就绪队列中的线程重新获取锁。

实例1:Wait(object);    

 public class MonitorTest{private object _lock = new object();public void FuncA(){lock (_lock){Console.WriteLine("进入函数A");Monitor.Wait(_lock);Console.WriteLine("退出函数A");}}public void FuncB(){Thread.Sleep(300);lock (_lock){Console.WriteLine("进入函数B");Thread.Sleep(3000);Monitor.Pulse(_lock);Thread.Sleep(3000);Console.WriteLine("退出函数B");}}}调用:MonitorTest monitorTest = new MonitorTest();
Task.Run(() => monitorTest.FuncA());
Task.Run(() => monitorTest.FuncB());

首先线程A通过wait方法释放锁,让线程B获取锁后成功开始执行,线程A进入等待队列,线程B执行过程中不再需要锁定对象后,则会调用pulse发送释放锁的信号,让收到信号的线程A从等待队列进入就绪队列,当线程B执行完成释放锁后,线程A重新获得锁,继续执行。

可以看到在线程B中发出Pulse信号后,线程A收到信号,进入就绪队列,此时线程B还没有释放锁,直到线程完成3s等待后,线程A才重新获取锁,wait(object)才返回。

说明1:发出pulse信号并不是释放锁,只是给等待队列中发送一个信号,收到信号的等待线程就会移动到就绪队列。

说明2:收到信号的Wait(object);不会立即返回,必须等到重新获取到锁后,才会返回,继续往下执行。如果收不到pulse信号,此等待将无限期的等待下去。

实例2:wait(object, int32);

此函数会在指定的时间内等待信号,如果超时则会自动进入就绪线程。当重新获取锁返回后,返回值为fasle.表示未在指定时间内获取锁,否则返回true.

public class MonitorTest
{private object _lock = new object();public void FuncA(){lock (_lock){Console.WriteLine("进入函数A");bool flag = false;while (!flag){flag = Monitor.Wait(_lock, 1000);Console.WriteLine("是否真实信号:" + flag);}Console.WriteLine("是否真实信号:" + flag);Console.WriteLine("退出函数A");}}public void FuncB(){Thread.Sleep(300);lock (_lock){Console.WriteLine("进入函数B");Thread.Sleep(3000);//Monitor.Pulse(_lock);Console.WriteLine("退出函数B");}}}调用:
MonitorTest monitorTest = new MonitorTest();
Task.Run(() => monitorTest.FuncA());
Task.Run(() => monitorTest.FuncB());

说明1:这里我们在线程B中,并没有发出pulse信号,线程也没有无限期等待。

说明2:如果我们在2s超时前,在线程B中发送pulse信号,则返回值为true.

说明3:无论我们发不发信号,线程A必须在线程B释放锁后,重新获得锁才会返回,继续执行,跟wait(object)一致。

如果超时时间设置为Timeout.Infinite,这与wait(object)一样,如果设置为0,则立即释放锁,进入就绪队列。

使用Wait/Pulse需要注意:

  • Wait / Pulse不能lock块之外使用,否则会抛异常。
  • Pulse最多释放一个线程,而PulseAll释放所有线程。
  • Wait会立即释放当前持有的锁,然后进入阻塞,等待脉冲
  • 收到脉冲会立即尝试重新获取锁,如果在指定时间内重新获取,则返回true,如果在超过指定时间获取,则返回false,如果没有获取锁,则一直阻塞不会返回

性能方面,调用Pulse花费大概约是在等待句柄上调用Set三分之一的时间。但是,使用WaitPulse进行信号同步,对比事件等待句柄有以下缺点:

  • Wait / Pulse不能跨越应用程序域和进程使用。

  • 必须通过锁保护所有信号同步逻辑涉及的变量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/627947.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matlab交互式的局部放大图

在数据可视化中,很多时候需要对某一区间的数据进行局部放大,以获得对比度更高的可视化效果。下面利用 MATLAB 语言实现一个交互式的局部放大图绘制。 源码自行下载: 链接:https://pan.baidu.com/s/1yItVSinh6vU4ImlbZW6Deg?pwd9d…

《2023年度程序员收入报告》 :旧金山位居第一,北京程序员中位数超60万元

2024年刚刚拉开序幕,备受瞩目的程序员薪资调研报告再度登场。由知名数据采集平台levels.fyi 搜集并整理了《2023年全球程序员收入报告》,为我们揭示了程序员最新的收入情况,其中有哪些值得关注的亮点呢? 行情向好,大多…

burp靶场——XXE注入

XML 外部实体 (XXE) 注入 1. 什么是xxe漏洞: https://portswigger.net/web-security/xxe#what-is-xml-external-entity-injection XML 外部实体注入(也称为 XXE)是一种 Web 安全漏洞,允许攻击者干扰应用程序对 XML 数据的处理。…

GEE:机器学习分类中每个类别的概率图像可视化

作者:CSDN @ _养乐多_ 在 Google Earth Engine(GEE) 中应用机器学习分类器进行多分类时,有一个需求是想知道每个像素对于每个类别的分类概率。 比如在进行随机森林分类时,每个决策树会生成一个类别,通过投票选择票数最多的类别作为最终分类。除了最终分类结果,其他类别…

Pandas.DataFrame.groupby() 数据分组(数据透视、分类汇总) 详解 含代码 含测试数据集 随Pandas版本持续更新

关于Pandas版本: 本文基于 pandas2.1.2 编写。 关于本文内容更新: 随着pandas的stable版本更迭,本文持续更新,不断完善补充。 Pandas稳定版更新及变动内容整合专题: Pandas稳定版更新及变动迭持续更新。 Pandas API参…

计算机组成原理 运输层

文章目录 运输层运输层协议概述进程之间的通信运输层的两个主要协议运输层的端口 用户数据报协议 UDPUDP 概述UDP 的首部格式 传输控制协议 TCP 概述TCP 最主要的特点TCP 的连接 可靠传输的工作原理停止等待协议连续 ARQ协议 TCP 报文段的首部格式TCP 可靠传输的实现以字节为单…

TensorRT模型优化部署 (八)--模型剪枝Pruning

系列文章目录 第一章 TensorRT优化部署(一)–TensorRT和ONNX基础 第二章 TensorRT优化部署(二)–剖析ONNX架构 第三章 TensorRT优化部署(三)–ONNX注册算子 第四章 TensorRT模型优化部署(四&am…

Go-安装与基础语法

TOC 1. Go 安装与环境变量 1.1 下载 需要从Go语言的官方网站下载适合你操作系统的Go语言安装包。Go语言支持多种操作系统,包括Windows、Linux和Mac OS。 对于Windows用户,下载.msi文件,然后双击该文件,按照提示进行安装即可。…

python的装饰器详解

目录 一:介绍 二:在方法中使用 三:在类中使用 四:python自带的装饰器 一:介绍 Python的装饰器是一种高阶函数,它允许你在不改变函数内部逻辑的情况下,给函数添加额外的功能。装饰器本质上是…

【C++进阶】心心念念的红黑树,它来了!

👦个人主页:Weraphael ✍🏻作者简介:目前学习C和算法 ✈️专栏:C航路 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞&#x1…

Spring框架是如何解决Bean创建过程中的循环依赖问题的

引言 本文主要梳理了Spring框架Bean创建过程中应对循环依赖问题的相关源码。我在手写super-mini-webpackhttps://blog.csdn.net/q1424966670/article/details/135628531?spm1001.2014.3001.5502的时候也介绍过解决循环依赖的算法:Map记忆化搜索。可以猜测这段源码…

ACL【新华三与华为的区别】

【解释】acl简单点解释就是,一套根据需求而设置的规则 【背景】 192.168.1.0/24 网段不允许访问 192.168.2.0/24 网段,要求使用基本 ACL 实现20_1 可以访问 20_6 的 TELNET 服务,但不能访问 FTP 服务 【操作步骤】 {易混点 }:1. …

机器学习周刊第六期:哈佛大学机器学习课、Chatbot Ul 2.0 、LangChain v0.1.0、Mixtral 8x7B

— date: 2024/01/08 — 吴恩达和Langchain合作开发了JavaScript 生成式 AI 短期课程:《使用 LangChain.js 构建 LLM 应用程序》 大家好,欢迎收看第六期机器学习周刊 本期介绍10个内容,涉及Python、机器学习、大模型等,目录如下&#xff…

Miracast手机高清投屏到电视(免费)

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl Miracast概述 Miracast是一种无线显示标准,它允许支持Miracast的设备之间通过Wi-Fi直接共享音频和视频内容,实现屏幕镜像或扩展显示。这意味着你可以…

C++常用类

1、QString 字符串类 QString 是Qt的字符串类,与C的std::string相比,不再使用ASCII编码。QString使用的Unicode编码。 QString 完全支持中文, 但是由于不同的技术可能会采用不同的编码。有时候也会遇到中文编码的一致性问题。 如果后续的学习…

PointMixer: MLP-Mixer for Point Cloud Understanding

Abstract MLP-Mixer 最近崭露头角,成为对抗CNNs和Transformer领域的新挑战者。尽管相比Transformer更为简单,但通道混合MLPs和令牌混合MLPs的概念在图像识别任务中取得了显著的性能。与图像不同,点云本质上是稀疏、无序和不规则的,这限制了直接将MLP-Mixer用于点云理解。为…

i18n多国语言Internationalization的实现

i18n 是"Internationalization”的缩写,这个术语来源于英文单词中首尾字母“”和“n”以及中间的字符数(共计18个字符) 当我们需要开发不同语言版本时,就可以使用i18n多国语言的一个操作处理,i18n主要实现那一方面的内容呢?…

项目压测优化实践思路

👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring原理、JUC原理、Kafka原理、分布式技术原理、数据库技术🔥如果感觉博主的文章还不错的…

日本樱岛火山喷发遥感卫星影像监测

日本樱岛火山喷发监测 当地时间2024年1月9日15时许,位于日本九州地区鹿儿岛县的樱岛南岳山顶火山口,开始喷发,火山烟雾从火山口上升至空中1200米左右。目前,日本气象厅将樱岛的火山警戒级别维持在3级,限制民众入山。 火…

HCS私有云简介

1、HCS简介和发展史 华为云产品:私有云和公有云,现在的私有云已经和公有云越来越像了FusionSphere是华为的一个品牌2016年,在5.0版本的时候,华为Openstack叫FusionSphere Openstack 5.0,底层用的是suse操作系统&#…