C# 中的多线程同步机制:lock、Monitor 和 Mutex 用法详解
在多线程编程中,线程同步是确保多个线程安全地访问共享资源的关键技术。C# 提供了几种常用的同步机制,其中 lock、Monitor 和 Mutex 是最常用的同步工具。本文将全面介绍这三种同步机制的用法、优缺点以及适用场景,帮助开发者在多线程开发中做出合适的选择。
1. lock 关键字
1.1 概述
在 C# 中,lock 关键字是用于线程同步的最常用工具之一。lock 是 Monitor.Enter() 和 Monitor.Exit() 的语法糖,通过锁住一个共享资源来确保在同一时刻只有一个线程可以访问它。lock 适用于同一个进程中的线程同步,尤其是在多个线程访问共享数据时,能够有效地防止数据竞态和线程安全问题。
1.2 用法
lock 关键字的常见用法是围绕一个对象的引用,将其作为锁对象来同步线程。通常,lock 语句会包装一个临界区(共享资源访问区),当一个线程执行完临界区代码后,另一个线程才能进入临界区。
示例代码:
using System;
using System.Threading;class Program
{private static readonly object _lock = new object(); // 锁对象static void Main(){Thread t1 = new Thread(DoWork);Thread t2 = new Thread(DoWork);t1.Start();t2.Start();}static void DoWork(){lock (_lock) // 获取锁{Console.WriteLine("线程进入临界区...");Thread.Sleep(1000); // 模拟处理时间Console.WriteLine("线程离开临界区...");}}
}
说明:
- 在
lock (_lock)中,_lock是锁对象。lock保证了在同一时刻只有一个线程可以进入lock语句块内部的代码。 lock会在代码块执行完毕后自动释放锁,无需手动释放。
1.3 优缺点
优点:
- 语法简洁,易于理解和使用。
- 自动释放锁,减少了因为忘记释放锁而导致死锁的风险。
缺点:
- 只能用于同一个进程中的线程之间的同步,不能跨进程使用。
- 无法提供更多的同步控制,比如等待和通知机制。
2. Monitor 类
2.1 概述
Monitor 类是 C# 提供的底层同步机制,比 lock 更加灵活和精细。Monitor 提供了对锁的手动控制,允许你在获取锁后,等待其他线程的通知或条件满足才能继续执行。Monitor 适合那些需要更多同步控制的场景,比如等待和通知机制。
2.2 用法
Monitor 类提供了几个关键的方法:
Enter(object obj):尝试获取锁,如果成功,线程继续执行。Exit(object obj):释放锁,允许其他线程访问锁定的资源。Wait(object obj):使当前线程等待,直到其他线程通知它。Pulse(object obj):唤醒一个等待该锁的线程。PulseAll(object obj):唤醒所有等待该锁的线程。
示例代码:
using System;
using System.Threading;class Program
{private static readonly object _lock = new object(); // 锁对象static void Main(){Thread t1 = new Thread(DoWork);Thread t2 = new Thread(DoWork);t1.Start();t2.Start();}static void DoWork(){Monitor.Enter(_lock); // 获取锁try{Console.WriteLine("线程进入临界区...");Thread.Sleep(1000); // 模拟工作Console.WriteLine("线程离开临界区...");}finally{Monitor.Exit(_lock); // 确保释放锁}}
}
说明:
Monitor.Enter(_lock)获取锁,Monitor.Exit(_lock)释放锁。Monitor更加底层,提供了细粒度的控制,适用于复杂的同步场景。- 使用
try/finally语句确保即使在发生异常时,也能释放锁。
2.3 优缺点
优点:
- 比
lock更灵活,支持等待和通知机制,如Wait、Pulse和PulseAll。 - 适用于需要更多控制的同步场景。
缺点:
- 使用起来相对复杂,容易出错,尤其是在手动管理锁时。
- 只支持同一进程内的线程同步。
3. Mutex 类
3.1 概述
Mutex 是 C# 中用于跨进程同步的同步机制。与 lock 和 Monitor 主要用于线程同步不同,Mutex 支持跨进程同步,因此可以用来在不同进程中协调对共享资源的访问。Mutex 的使用相对复杂,但它适用于需要在不同进程间进行同步的场景。
3.2 用法
Mutex 的使用方式与 lock 类似,但它允许在不同的进程间进行同步。Mutex 具有以下关键方法:
WaitOne():请求获取互斥锁。ReleaseMutex():释放互斥锁,允许其他线程或进程获取锁。
示例代码:
using System;
using System.Threading;class Program
{private static Mutex mutex = new Mutex(); // 创建互斥体static void Main(){Thread t1 = new Thread(DoWork);Thread t2 = new Thread(DoWork);t1.Start();t2.Start();}static void DoWork(){mutex.WaitOne(); // 请求互斥锁Console.WriteLine("线程进入临界区...");Thread.Sleep(1000); // 模拟工作Console.WriteLine("线程离开临界区...");mutex.ReleaseMutex(); // 释放互斥锁}
}
说明:
mutex.WaitOne()用来请求互斥锁,直到其他线程或进程释放锁。mutex.ReleaseMutex()用来释放互斥锁,允许其他线程或进程获取锁。
3.3 优缺点
优点:
Mutex支持跨进程同步,适用于多个进程间的线程同步。- 可以控制同一资源在不同进程间的访问。
缺点:
- 性能开销较大,尤其在涉及跨进程同步时。
- 使用起来较为复杂,需要手动释放锁。
4. lock、Monitor 和 Mutex 的对比
| 特性/方法 | lock | Monitor | Mutex |
|---|---|---|---|
| 使用场景 | 线程同步,适用于同一进程内的线程 | 线程同步,提供更多控制(如等待、通知) | 跨进程同步和同一进程内的线程同步 |
| 性能 | 性能较好,简便易用 | 性能稍差,但提供更多控制 | 性能开销较大,尤其是跨进程同步时 |
| 跨进程支持 | 不支持 | 不支持 | 支持跨进程同步 |
| 异常处理 | 自动处理锁的释放 | 需要手动释放锁 | 需要手动释放锁 |
| 使用复杂度 | 简单易用 | 较复杂,需要手动处理等待和通知 | 较复杂,涉及跨进程操作 |
| 特点 | 语法简洁 | 更底层,支持等待和通知机制 | 可以跨进程同步 |
适用场景:
lock:当你只需要简单的线程同步,并且仅在同一个进程内操作时,lock是最合适的选择。Monitor:当你需要更多控制,尤其是线程的等待、通知机制时,Monitor是更好的选择。Mutex:当你需要跨进程同步时,Mutex是唯一的选择,它适用于多个进程中的线程同步。
5. 总结
在 C# 中,lock、Monitor 和 Mutex 是常见的同步机制,它们分别适用于不同的多线程同步需求:
lock适合简单的线程同步,语法简洁且易于使用。Monitor提供了更底层的同步控制,适用于复杂的同步需求,如线程的等待、通知等。Mutex适用于跨进程的同步,尤其在不同进程间共享资源时,Mutex是必不可少的工具。
根据具体的应用场景,合理选择同步机制能够有效提高程序的性能和稳定性,避免资源竞争和线程安全问题。
相关文章:
C# 中的多线程同步机制:lock、Monitor 和 Mutex 用法详解
在多线程编程中,线程同步是确保多个线程安全地访问共享资源的关键技术。C# 提供了几种常用的同步机制,其中 lock、Monitor 和 Mutex 是最常用的同步工具。本文将全面介绍这三种同步机制的用法、优缺点以及适用场景,帮助开发者在多线程开发中做…...
【通义万相】蓝耘智算 | 开源视频生成新纪元:通义万相2.1模型部署与测评
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈人工智能与大模型应用 ⌋ ⌋ ⌋ 人工智能(AI)通过算法模拟人类智能,利用机器学习、深度学习等技术驱动医疗、金融等领域的智能化。大模型是千亿参数的深度神经网络(如ChatGPT&…...
期权帮|中证1000股指期权交割结算价怎么算?
期权帮锦鲤三三每日分享期权知识,帮助期权新手及时有效地掌握即市趋势与新资讯! 中证1000股指期权交割结算价怎么算? 一、按照最后交易日结算价: (1)计算方法:最后交易日标的指数(…...
Python 面向对象高级编程-定制类
目录 __str__ __iter__ __getitem__ __getattr__ __call__ 小结 看到类似__slots__这种形如__xxx__的变量或者函数名就要注意,这些在Python中是有特殊用途的。 __slots__我们已经知道怎么用了,__len__()方法我们也知道是为了能让class作用于len()…...
qt creator示例空白
通常情况下,进入qt后,就会弹出以下窗口: 但如果出现示例空白,那可能是因为 Qt Creator 无法正确识别 Qt 的安装路径或配置。 解决: 点击“添加”: 然后跳转到你的qmake.exe的目录,例如我的qmak…...
MyBatis-Plus 与 Spring Boot 的最佳实践
在现代 Java 开发中,MyBatis-Plus 和 Spring Boot 的结合已经成为了一种非常流行的技术栈。MyBatis-Plus 是 MyBatis 的增强工具,提供了许多便捷的功能,而 Spring Boot 则简化了 Spring 应用的开发流程。本文将探讨如何将 MyBatis-Plus 与 Spring Boot 进行整合,并分享一些…...
TDengine 中的标签索引
简介 本节说明 TDengine 的索引机制。在 TDengine 3.0.3.0 版本之前(不含),默认在第一列 TAG 上建立索引,但不支持给其它列动态添加索引。从 3.0.3.0 版本开始,可以动态地为其它 TAG 列添加索引。对于第一个 TAG 列上…...
工业自动化核心:BM100 信号隔离器的强大力量
安科瑞 吕梦怡 18706162527 BM100系列信号隔离器可以对电流、电压等电量参数或温度、电阻等非电量参数进行快速精确测量,经隔 离转换成标准的模拟信号输出。既可以直接与指针表、数显表相接,也可以与自控仪表(如PLC)、各种 A/D …...
Ascend开发板镜像烧录、联网、其他设备访问
Ascend开发板镜像烧录、联网、外部访问 1.1 Ascend开发板制卡方式一:镜像烧录 SD卡插入读卡器,读卡器插入PC的USB接口 烧录镜像前,先格式化一下SD卡 参考教程:格式化SD卡、修复烧写系统失败的SD卡 WinR,输入cmd DIS…...
Llama-Factory框架下的Meta-Llama-3-8B-Instruct模型微调
目录 引言 Llama - Factory 训练框架简介: Meta - Llama - 3 - 8B - Instruct 模型概述: Lora 方法原理及优势: 原理 优势 环境准备: 部署环境测试: 数据准备: 模型准备: 模型配置与训练࿱…...
MySQL进阶-分析查询语句EXPLAIN
概述 能做什么? 表的读取顺序 数据读取操作的操作类型 哪些索引可以使用 哪些索引被实际使用 表之间的引用 每张表有多少行被优化器查询 官网介绍 https://dev.mysql.com/doc/refman/5.7/en/explain-output.html https://dev.mysql.com/doc/refman/8.0/…...
Python 高级编程与实战:构建数据可视化应用
在前几篇文章中,我们探讨了 Python 的基础语法、面向对象编程、函数式编程、元编程、性能优化、调试技巧、数据科学、机器学习、Web 开发、API 设计、网络编程、异步IO、并发编程、设计模式与软件架构、性能优化与调试技巧、分布式系统、微服务架构、自动化测试框架以及 RESTf…...
学习threejs,Animation、Core、CustomBlendingEquation、Renderer常量汇总
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️Animation常量汇总1.1.1 循…...
Java直通车系列14【Spring MVC】(深入学习 Controller 编写)
目录 基本概念 编写 Controller 的步骤和要点 1. 定义 Controller 类 2. 映射请求 3. 处理请求参数 4. 调用业务逻辑 5. 返回响应 场景示例 1. 简单的 Hello World 示例 2. 处理路径变量和请求参数 3. 处理表单提交 4. 处理 JSON 数据 5. 异常处理 基本概念 Cont…...
【蓝桥杯集训·每日一题2025】 AcWing 5539. 牛奶交换 python
AcWing 5539. 牛奶交换 Week 3 3月6日 题目描述 农夫约翰的 N N N 头奶牛排成一圈,使得对于 1 , 2 , … , N − 1 1,2,…,N−1 1,2,…,N−1 中的每个 i i i,奶牛 i i i 右边的奶牛是奶牛 i 1 i1 i1,而奶牛 N N N 右边的奶牛是奶牛 …...
Mybatis缓存机制(一级缓存和二级缓存)
前言 为什么要学习Mybatis 缓存机制? 学习Mybatis 缓存机制,可以有效解决 数据库的压力,提高数据库的性能。 例如:你要 对tb_user 表 ,查询 所有用户的信息,并且多次查询所有用户信息。我们知道第一次查询表信息流…...
设计模式--单例模式
一、单例模式代码实现 public class DatabaseConnection {// 1. 私有静态实例变量private static DatabaseConnection instance;// 2. 私有构造函数,防止外部直接创建实例private DatabaseConnection() {// 初始化数据库连接System.out.println("Database con…...
ubuntu22.04本地部署OpenWebUI
一、简介 Open WebUI 是一个可扩展、功能丰富且用户友好的自托管 AI 平台,旨在完全离线运行。它支持各种 LLM 运行器,如 Ollama 和 OpenAI 兼容的 API,并内置了 RAG 推理引擎,使其成为强大的 AI 部署解决方案。 二、安装 方法 …...
2025-3-7二叉树的线索化
一、中序线索化 代码其实就是和中序遍历相似,增加了两个标志位 ltag rtag。 完整的代码: 二、先序线索化: 三、后序线索化: 总结:其核心其实还是遍历算法的改造。 并且注意处理最后一个被访问的节点。...
以商业思维框架为帆,驭创业浪潮前行
创业者踏入商海,如同航海家奔赴未知海域,需有清晰的思维罗盘指引方向。图中“为什么—用什么—怎么做—何人做—投入产出”的商业框架,正是创业者破解商业谜题的密钥,从需求洞察到落地执行,为创业之路铺就逻辑基石。 …...
从零构建现代化Web控制面板:安全架构与实时监控实践
1. 项目概述:一个为开发者设计的现代化控制面板最近在GitHub上看到一个挺有意思的项目,叫clawpanel,作者是kweephyo-pmt。光看名字,你可能会联想到“爪子”和“面板”,感觉像是个带点攻击性或工具属性的管理界面。实际…...
Excel MCP Server终极指南:3步实现无界面Excel自动化处理
Excel MCP Server终极指南:3步实现无界面Excel自动化处理 【免费下载链接】excel-mcp-server A Model Context Protocol server for Excel file manipulation 项目地址: https://gitcode.com/gh_mirrors/ex/excel-mcp-server 你是否厌倦了手动操作Excel的繁琐…...
在线Graphviz图表编辑器:3步创建专业技术流程图
在线Graphviz图表编辑器:3步创建专业技术流程图 【免费下载链接】GraphvizOnline Lets Graphviz it online 项目地址: https://gitcode.com/gh_mirrors/gr/GraphvizOnline 还在为复杂的技术图表绘制而烦恼吗?GraphvizOnline作为一款革命性的在线G…...
终极罗技PUBG鼠标宏配置指南:5步告别压枪烦恼
终极罗技PUBG鼠标宏配置指南:5步告别压枪烦恼 【免费下载链接】logitech-pubg PUBG no recoil script for Logitech gaming mouse / 绝地求生 罗技 鼠标宏 项目地址: https://gitcode.com/gh_mirrors/lo/logitech-pubg 还在为《绝地求生》中疯狂上跳的枪口而…...
SVG与CSS变量驱动的自动化品牌视觉生成技术实践
1. 项目概述:一分钟品牌塑造的实践宝库在品牌营销和创意设计领域,一个常见的痛点是如何快速、高效地生成高质量的视觉品牌资产。无论是初创公司需要一个临时的Logo,还是内容创作者想为新的系列视频设计一个统一的片头,传统的品牌设…...
AI驱动工作流自动化:从原理到实践,构建智能效率引擎
1. 项目概述:当AI遇上工作流,一场效率革命正在发生最近在GitHub上看到一个名为“WorkflowAI/WorkflowAI”的项目,这个名字本身就充满了想象空间。作为一个长期与各种自动化工具和效率方法论打交道的人,我立刻意识到,这…...
构建个人知识库:从碎片化代码到结构化知识体系
1. 项目概述:从“ClawCode”看个人知识库的构建与价值最近在和一些开发者朋友交流时,发现一个普遍现象:大家电脑里都散落着无数代码片段、配置脚本、临时笔记和项目心得。这些“数字碎片”价值巨大,但往往因为缺乏有效的组织&…...
Cursor与Figma通过MCP协议实现AI辅助设计与开发同步
1. 项目概述:当代码编辑器与设计工具“开口说话”最近在开发者社区里,一个名为“cursor-talk-to-figma-mcp”的项目引起了我的注意。这个由开发者“hamadoun1760”开源的仓库,名字直译过来就是“Cursor与Figma对话的MCP”。乍一看,…...
无代码物联网实战:基于ESP32与WipperSnapper的泳池水温监测方案
1. 项目概述:告别繁琐编程,用无代码方案守护泳池水温又到了打理泳池的季节,除了常规的清洁和化学平衡,水温其实是个挺关键的指标。水温不仅影响游泳的舒适度,也关系到泳池加热设备的能耗和泳池化学品的反应速率。以前想…...
工控一体机电脑核心性能特征解析:从选型到部署的实战指南
1. 项目概述:为什么我们需要重新审视工控一体机电脑?在工业自动化、智能制造、智慧零售乃至边缘计算这些听起来高大上的领域里,有一类设备常常是幕后的“无名英雄”,它不像机器人手臂那样引人注目,也不像云端服务器那样…...
