c# 多线程环境下控制对共享资源访问的办法
- Monitor:
- 定义:
Monitor
是 C# 中最基本的同步机制,通过Enter
和Exit
方法来控制对共享资源的访问。它提供了排他锁的功能,确保在任何时刻只有一个线程可以访问共享资源。 - 优点:简单易用,适合对临界区进行粗粒度的同步控制。
- 缺点:只能实现排它锁,不能实现读写锁,性能相对较低。
- 定义:
class Program
{
static readonly object _lock = new object();
static int _counter = 0; static void Main()
{
for (int i = 0; i < 10; i++)
{
new Thread(IncrementCounter).Start();
} Console.ReadKey();
} static void IncrementCounter()
{
lock (_lock)
{
_counter++;
Console.WriteLine($"Counter: {_counter}");
}
}
}
- Mutex:
- 定义:
Mutex
是一个操作系统对象,用于在进程间共享,通过WaitOne
和ReleaseMutex
来控制对共享资源的访问。它提供了进程间的同步能力。 - 优点:可跨进程使用,适合在进程间进行同步。
- 缺点:相比
Monitor
,性能开销较大,因为涉及到系统调用。
- 定义:
class Program
{
static Mutex _mutex = new Mutex();
static int _counter = 0; static void Main()
{
for (int i = 0; i < 10; i++)
{
new Thread(IncrementCounter).Start();
} Console.ReadKey();
} static void IncrementCounter()
{
_mutex.WaitOne();
_counter++;
Console.WriteLine($"Counter: {_counter}");
_mutex.ReleaseMutex();
}
}
Mutex
- ReaderWriterLockSlim:
- 定义:
ReaderWriterLockSlim
实现了读写分离锁,允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。这种机制适用于读多写少的场景。 - 优点:适合读多写少的场景,提高了并发性能。
- 缺点:相对复杂,可能会引起死锁,不支持递归锁。
- 定义:
class Program
{
static ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
static int _counter = 0; static void Main()
{
for (int i = 0; i < 5; i++)
{
new Thread(ReadCounter).Start();
new Thread(IncrementCounter).Start();
} Console.ReadKey();
} static void ReadCounter()
{
_rwLock.EnterReadLock();
Console.WriteLine($"Counter: {_counter}");
_rwLock.ExitReadLock();
} static void IncrementCounter()
{
_rwLock.EnterWriteLock();
_counter++;
Console.WriteLine($"Counter incremented to: {_counter}");
_rwLock.ExitWriteLock();
}
}
ReaderWriterLockSlim
- Semaphore:
- 定义:
Semaphore
是一个信号量,用于控制同时访问共享资源的线程数量。通过WaitOne
和Release
方法,可以控制访问资源的线程数量。 - 优点:可以控制多个线程同时访问共享资源的数量,灵活性较高。
- 缺点:相对于其他机制,使用起来较为复杂,需要谨慎处理信号量的释放。
- 定义:
class Program
{
static Semaphore _semaphore = new Semaphore(2, 2); // Allow 2 threads to access the resource simultaneously
static int _counter = 0; static void Main()
{
for (int i = 0; i < 5; i++)
{
new Thread(IncrementCounter).Start();
} Console.ReadKey();
} static void IncrementCounter()
{
_semaphore.WaitOne();
_counter++;
Console.WriteLine($"Counter: {_counter}");
_semaphore.Release();
}
}
Semaphore
- SemaphoreSlim:
- 定义:
SemaphoreSlim
是轻量级的信号量,与Semaphore
类似,用于控制同时访问共享资源的线程数量,但相比Semaphore
更轻量级。 - 优点:相比
Semaphore
,SemaphoreSlim
的开销更小,适用于资源访问频繁的场景。 - 缺点:与
Semaphore
相比,功能上略有限制,例如没有Release(Int32)
方法,只能递增信号量一个单位。
- 定义:
class Program
{
static SemaphoreSlim _semaphore = new SemaphoreSlim(2, 2); // Allow 2 threads to access the resource simultaneously
static int _counter = 0; static void Main()
{
for (int i = 0; i < 5; i++)
{
new Thread(IncrementCounter).Start();
} Console.ReadKey();
} static void IncrementCounter()
{
_semaphore.Wait();
_counter++;
Console.WriteLine($"Counter: {_counter}");
_semaphore.Release();
}
}
SemaphoreSlim
- lock:
- 定义:
lock
是 C# 中的关键字,用于在代码块级别实现互斥锁,保护共享资源不被多个线程同时访问。 - 优点:简单易用,适合对临界区进行细粒度的同步控制,编写起来比较方便。
- 缺点:只能用于单线程内部的同步,不能跨越线程或进程,如果不小心使用会导致死锁。
- 定义:
class Program
{
static readonly object _lock = new object();
static int _counter = 0; static void Main()
{
for (int i = 0; i < 5; i++)
{
new Thread(IncrementCounter).Start();
} Console.ReadKey();
} static void IncrementCounter()
{
lock (_lock)
{
_counter++;
Console.WriteLine($"Counter: {_counter}");
}
}
}
lock
c# 多线程环境下控制对共享资源访问的办法的更多相关文章
- 什么是多线程环境下的伪共享(false sharing)?
伪共享是多线程系统(每个处理器有自己的局部缓存)中一个众所周知的性能问 题.伪共享发生在不同处理器的上的线程对变量的修改依赖于相同的缓存行,如 下图所示: 伪共享问题很难被发现,因为线程可能访问完全不 ...
- SQLite在多线程环境下的应用
文一 SQLite的FAQ里面已经专门说明,先贴出来.供以后像我目前的入门者学习. (7) 多个应用程序或者同一个应用程序的多个例程能同时存取同一个数据库文件吗? 多进程可以同时打开同一个数据库,也可 ...
- HttpClient在多线程环境下踩坑总结
问题现场 在多线程环境下使用HttpClient组件对某个HTTP服务发起请求,运行一段时间之后发现客户端主机CPU利用率呈现出下降趋势,而不是一个稳定的状态. 而且,从程序日志中判断有线程处于han ...
- C++多线程环境下的构造函数
多线程的环境里,我们总不可避免要使用锁.于是一个常见的场景就是: class ObjectWithLock { private: std::mutex mtx_; SomeResType shared ...
- Asp.Net在多线程环境下的状态存储问题
在应用开发中,我们经常需要设置一些上下文(Context)信息,这些上下文信息一般基于当前的会话(Session),比如当前登录用户的个人信息:或者基于当前方法调用栈,比如在同一个调用中涉及的多个层次 ...
- 一个由单例模式在多线程环境下引发的 bug
问题症状 HTTP 日志系统,老是出现日志信息覆盖的情况.比如同时调用 A 接口和 B 接口,B 接口请求响应信息变成了 A 接口请求响应相关信息.这个问题在并发量大的情况下越来越严重. 问题初步分析 ...
- C#多线程环境下调用 HttpWebRequest 并发连接限制
C#多线程环境下调用 HttpWebRequest 并发连接限制 .net 的 HttpWebRequest 或者 WebClient 在多线程情况下存在并发连接限制,这个限制在桌面操作系统如 win ...
- 多线程环境下非安全Dictionary引起的“已添加了具有相同键的项”问题
问题: 代码是在多线程环境下,做了简单的Key是否存的判断, 测试代码如下: public class Program { static Dictionary<string, Logger> ...
- 多线程环境下的UI异步操作
转自原文 多线程环境下的UI异步操作 解决VS中,线程间不可互操作的问题,一揽子解决方案: 一.首先,定义一个类:SetControlProperty using System.Reflection; ...
- 单例模式在多线程环境下的lazy模式为什么要加两个if(instance==null)
刚才在看阿寻的博客”C#设计模式学习笔记-单例模式“时,发现了评论里有几个人在问单例模式在多线程环境下为什么lazy模式要加两个if进行判断,评论中的一个哥们剑过不留痕,给他们写了一个demo来告诉他 ...
随机推荐
- C#开发的股票盯盘小工具——摸鱼助手,附源码
写了个盯盘小工具,最近发现很多炒股的小伙伴,上班期间看手机频繁是不是影响不好?电脑上打开交易软件,那影响是不是更不好?所以我就写了个小工具,给大家"摸鱼"用.虽然是摸鱼用,但是平常 ...
- foxy rviz2 "rviz_common/Time"报错问题
报错内容 The class required for this panel, 'rviz_common/Time', could not be loaded. Error: According to ...
- java检测当前CPU负载状态的方法
1.java检测当前CPU负载状态 在Java中,直接检测CPU负载状态并不像在操作系统命令行中那样简单,因为Java标准库并没有直接提供这样的功能.但是,我们可以通过几种方法间接地获取CPU负载信息 ...
- bash: _get_comp_words_by_ref: command not found 报错
没有安装补全的包 错误信息 bash: _get_comp_words_by_ref: command not found 表明你的 shell 中可能存在补全功能的问题. 通常,这种错误发生在你的系 ...
- Qt_Demo_1:实现一个简易的记事本
1 环境: 系统:windows 10 代码编写运行环境:Qt Creator 4.4.1 (community) GitHub:https://github.com/zhengcixi/Qt_De ...
- Easysearch:语义搜索、知识图和向量数据库概述
什么是语义搜索? 语义搜索是一种使用自然语言处理算法来理解单词和短语的含义和上下文以提供更准确的搜索结果的搜索技术.旨在更好地理解用户的意图和查询内容,而不仅仅是根据关键词匹配,还通过分析查询的语义和 ...
- 导出excel文件接口代码示例
导出excel文件接口代码示例 1.该导出接口,token不能通过请求头来传输,需要在get请求的参数中带出来2.验证token的方法除了在拦截器中统一拦截,针对get接口传参数的方式也需要单独在接口 ...
- 接口签名规则和Java实现签名和验签代码
接口签名规则和Java实现签名和验签代码 签名规则 签名生成的通用步骤如下: 第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用U ...
- 使用Python爬取公众号的合集内容
使用Python爬取公众号的合集 前言 ...最近老是更新关于博客的文章,很久没更新其他的了,然后写一下如何爬取微信公众号里面的图片吧! 先看看微信公众号的样子吧: 我爬取的是公众号的合集内容 讲解 ...
- 在SMT32程序HEX文件中加入固件版本信息
将固件版本信息定义成一个常量存放在程序中,需要的时候可以通过串口等接口查询代码版本信息,另一种,是利用编译器的语法,将固定的信息保存到某地. #define VERINFO_ADDR_BASE (0x ...