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来告诉他 ...
随机推荐
- linux下基于官方源码编译ipopt
linux下基于官方源码编译ipopt 1.C++依赖项安装升级 由于需要编译c++所以需要安装一系列的依赖: apt-get update apt-get -y upgrade apt instal ...
- windows下IPv6组播(C++、MFC)
Server #include <stdio.h> #include <Ws2tcpip.h> #include <winsock2.h> #pragma comm ...
- C#开发的股票盯盘小工具——摸鱼助手,附源码
写了个盯盘小工具,最近发现很多炒股的小伙伴,上班期间看手机频繁是不是影响不好?电脑上打开交易软件,那影响是不是更不好?所以我就写了个小工具,给大家"摸鱼"用.虽然是摸鱼用,但是平常 ...
- 适用于linux的bilibiliB站直播间弹幕爬虫脚本
适用于linux的bilibiliB站直播间弹幕爬虫脚本,命令行运行之,输入到命令行,部分内容参考自网络,代码底部可见原始代码出处 BUFF:然而,经测试,每次爬只能读取10条弹幕记录,这就使得在(s ...
- ros2 foxy订阅话题问题
代码片段 这部分代码在galactic版本编译是OK的,可在foxy下编译就出了问题 TeleopPanel::TeleopPanel(QWidget* parent) : rviz_common:: ...
- k8s——pod的yaml文件
理解什么是pod pod基于deployment创建,删除deployment,pod也会被删除 基础pod的yaml文件的资源清单 点击查看列表 | 参数名 | 类型 | 字段说明 | | ---- ...
- 算法学习笔记(15): Trie(字典树)
Trie树 Trie(字典树)是一种用于实现字符串检索的多叉树. Trie的每一个节点都可以通过 c 转移到下一层的一个节点. 我们可以看作可以通过某个字符转移到下一个字符串状态,直到转移到最终态为止 ...
- linux,curl命令发送各类请求详解
当你经常面对api时,curl将是你重要学习的工具,因为curl可以让你不需要浏览器也能作为Http客户端发送请求.而且它是跨平台的,Linux.Windows.Mac都会执行的很好. 一.curl ...
- opengrok源代码在线阅读平台搭建及字体修改
服务搭建 我所编写的docker-compose.yml如下,成功运行后将源码目录移动至 /data/opengrok/src ,重启容器使得opengrok快速更新索引 services: open ...
- 高通 LK阶段配置使用I2C-8
以MSM8953为例. 原文(有删改):https://blog.csdn.net/qq_29890089/article/details/108294710 项目场景 因为项目需要,需要在高通MSM ...