当前位置: 首页 > article >正文

用C#实现互斥操作

1、传统的lock

lock简单易用,适合大多数场景,但在高竞争用情况下可能会导致线程阻塞;

        Object obj = new object(); 
        void method1()
        {
            lock (obj)
            {
                // 进行互斥操作
            }
        }

2、SpinLock

SpinLock在低延迟情况下更有效,因为SpinLock会在忙等待(spin)中尝试获取锁;但在高竞用时,可能导致更高的CPU使用率。

SpinLock适合短时间锁定,而lock更通用。选择时需要根据具体的使用场景和性能需求来决定。

        SpinLock spinLock = new SpinLock();
        void method2()
        {
            bool lockTaken = false;
            spinLock.Enter(ref lockTaken);
            try
            {
                // 进行互斥操作
            }
            finally
            {
                if (lockTaken)
                {
                    spinLock.Exit(true);
                }
            }
        }

注意:

SpinLock.Exit方法中,参数决定是否在释放锁时记录锁的状态。一般情况下:

  • Exit(true):用于锁被当前线程正常获取,表示锁状态已被正确管理,适合在正常退出时使用。
  • Exit(false):用于锁可能被异常获取,通常在某些特殊情况下使用,表示不强制解除锁状态。

在大多数普通场景中,使用Exit(true)更为合适,Exit(false)则少用。

3、Mutex

Mutex可以跨进程使用,适合更广泛的场景

Mutex mutex = new Mutex();
mutex.WaitOne(); // 获取锁
try 
{
    // 进行互斥操作
} 
finally 
{
    mutex.ReleaseMutex(); // 释放锁
}

4、SemaphoreSlim

SemaphoreSlim用于限制同一时间访问资源的数量;

SemaphoreSlim semaphore = new SemaphoreSlim(1); // 初始化为1
await semaphore.WaitAsync(); // 获取锁
try 
{
    // 进行互斥操作
} 
finally 
{
    semaphore.Release(); // 释放锁
}

注意:Semaphore和SemaphoreSlim

Semaphore用于限制可访问共享资源的线程数量,SemaphoreSlim是轻量版的Semaphore,但是提供了类似的功能,更适合单进程中的线程同步。

using System;
using System.Threading;

class Program
{
    static SemaphoreSlim semaphore = new SemaphoreSlim(2); // 允许最多两个线程同时访问资源

    static void Main(string[] args)
    {
        for (int i = 0; i < 5; i++)
        {
            int threadNum = i;
            Thread t = new Thread(() => AccessResource(threadNum));
            t.Start();
        }
    }

    static void AccessResource(int threadNum)
    {
        Console.WriteLine($"线程 {threadNum} 尝试访问资源...");
        
        semaphore.Wait(); // 尝试获取信号量,如果已经有两个线程持有信号量,则阻塞
        
        Console.WriteLine($"线程 {threadNum} 获得了资源,正在处理...");
        Thread.Sleep(2000); // 模拟资源处理时间
        
        Console.WriteLine($"线程 {threadNum} 释放了资源...");
        semaphore.Release(); // 释放信号量,允许其他线程继续访问
    }
}

5、ReaderWriterLockSlim

ReaderWriterLockSlim则允许多个线程读取、但在写入时会独占访问;

ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();


rwLock.EnterReadLock(); // 获取读锁
try 
{
    // 进行读操作
} 
finally 
{
    rwLock.ExitReadLock(); // 释放读锁
}



rwLock.EnterWriteLock(); // 获取写锁
try 
{
    // 进行写操作
} 
finally 
{
    rwLock.ExitWriteLock(); // 释放写锁
}


http://www.kler.cn/news/362989.html

相关文章:

  • FPGA实现PCIE采集电脑端视频转SFP光口万兆UDP输出,基于XDMA+GTX架构,提供2套工程源码和技术支持
  • 【MySQL】表的增删改查(CRUD)
  • 【代码随想录Day50】图论Part02
  • 构建基于Spring Boot的现代论坛平台
  • 文通车牌识别相机在工地称重应用中的卓越表现
  • Git 文件大小写混乱?
  • Java爬虫之使用Selenium WebDriver 爬取数据
  • pycharm中鼠标选择文本会自动复制
  • @RequestBody的详解和使用
  • 怎么为pdf文件设置密码?几种PDF文件设置密码的方法推荐
  • 房屋租赁管理系统|基于java和小程序的房屋租赁管理系统小程序设计与实现(源码+数据库+文档)
  • 探索云计算:AWS、Azure、GCP云服务提供商详解
  • 2024java高频面试之JVM-第二弹
  • Spring boot快速集成开发
  • ABB防爆伺服电机HX系列 危险工业环境中的安全卫士
  • 「C/C++」C++ STL容器库 之 std::vector动态数组容器
  • 特斯拉Optimus:展望智能生活新篇章
  • 立仪科技:光谱共焦传感器精准测量玻璃
  • Spring框架如何高效的使用线程池
  • DEPT:DECOMPOSED PROMPT TUNING FOR PARAMETER-EFFICIENT FINE-TUNING
  • 【Python学习】Python基础,对于库和框架的讲解(优点缺点)小白必备的!!!
  • AST 技术学习
  • 【华为HCIP实战课程十五】OSPF的环路避免及虚链路,网络工程师
  • 10.19 RHCSA 作业
  • 【QT】常用控件(三)
  • (三)行为模式:11、模板模式(Template Pattern)(C++示例)