经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
c# 多线程环境下控制对共享资源访问的办法
来源:cnblogs  作者:我只吃饭不洗碗  时间:2024/7/31 15:01:36  对本文有异议
  1. Monitor:
    • 定义:Monitor 是 C# 中最基本的同步机制,通过 Enter 和 Exit 方法来控制对共享资源的访问。它提供了排他锁的功能,确保在任何时刻只有一个线程可以访问共享资源。
    • 优点:简单易用,适合对临界区进行粗粒度的同步控制。
    • 缺点:只能实现排它锁,不能实现读写锁,性能相对较低。

  

  1. class Program
  2. {
  3. static readonly object _lock = new object();
  4. static int _counter = 0;
  5. static void Main()
  6. {
  7. for (int i = 0; i < 10; i++)
  8. {
  9. new Thread(IncrementCounter).Start();
  10. }
  11. Console.ReadKey();
  12. }
  13. static void IncrementCounter()
  14. {
  15. Monitor.Enter(_lock);
  16. try
  17. {
  18. _counter++;
  19. Console.WriteLine($"Counter: {_counter}");
  20. }
  21. finally
  22. {
  23. Monitor.Exit(_lock);
  24. }
  25. }
  26. }
Monitor

 

  1. Mutex:
    • 定义:Mutex 是一个操作系统对象,用于在进程间共享,通过 WaitOne 和 ReleaseMutex 来控制对共享资源的访问。它提供了进程间的同步能力。
    • 优点:可跨进程使用,适合在进程间进行同步。
    • 缺点:相比 Monitor,性能开销较大,因为涉及到系统调用。

  

  1. class Program
  2. {
  3. static Mutex _mutex = new Mutex();
  4. static int _counter = 0;
  5. static void Main()
  6. {
  7. for (int i = 0; i < 10; i++)
  8. {
  9. new Thread(IncrementCounter).Start();
  10. }
  11. Console.ReadKey();
  12. }
  13. static void IncrementCounter()
  14. {
  15. _mutex.WaitOne();
  16. _counter++;
  17. Console.WriteLine($"Counter: {_counter}");
  18. _mutex.ReleaseMutex();
  19. }
  20. }
Mutex

 

  1. ReaderWriterLockSlim:
    • 定义:ReaderWriterLockSlim 实现了读写分离锁,允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。这种机制适用于读多写少的场景。
    • 优点:适合读多写少的场景,提高了并发性能。
    • 缺点:相对复杂,可能会引起死锁,不支持递归锁。

  

  1. class Program
  2. {
  3. static ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim();
  4. static int _counter = 0;
  5. static void Main()
  6. {
  7. for (int i = 0; i < 5; i++)
  8. {
  9. new Thread(ReadCounter).Start();
  10. new Thread(IncrementCounter).Start();
  11. }
  12. Console.ReadKey();
  13. }
  14. static void ReadCounter()
  15. {
  16. _rwLock.EnterReadLock();
  17. Console.WriteLine($"Counter: {_counter}");
  18. _rwLock.ExitReadLock();
  19. }
  20. static void IncrementCounter()
  21. {
  22. _rwLock.EnterWriteLock();
  23. _counter++;
  24. Console.WriteLine($"Counter incremented to: {_counter}");
  25. _rwLock.ExitWriteLock();
  26. }
  27. }
ReaderWriterLockSlim

 

  1. Semaphore:
    • 定义:Semaphore 是一个信号量,用于控制同时访问共享资源的线程数量。通过 WaitOne 和 Release 方法,可以控制访问资源的线程数量。
    • 优点:可以控制多个线程同时访问共享资源的数量,灵活性较高。
    • 缺点:相对于其他机制,使用起来较为复杂,需要谨慎处理信号量的释放。

  

  1. class Program
  2. {
  3. static Semaphore _semaphore = new Semaphore(2, 2); // Allow 2 threads to access the resource simultaneously
  4. static int _counter = 0;
  5. static void Main()
  6. {
  7. for (int i = 0; i < 5; i++)
  8. {
  9. new Thread(IncrementCounter).Start();
  10. }
  11. Console.ReadKey();
  12. }
  13. static void IncrementCounter()
  14. {
  15. _semaphore.WaitOne();
  16. _counter++;
  17. Console.WriteLine($"Counter: {_counter}");
  18. _semaphore.Release();
  19. }
  20. }
Semaphore

 

  1. SemaphoreSlim:
    • 定义:SemaphoreSlim 是轻量级的信号量,与 Semaphore 类似,用于控制同时访问共享资源的线程数量,但相比 Semaphore 更轻量级。
    • 优点:相比 SemaphoreSemaphoreSlim 的开销更小,适用于资源访问频繁的场景。
    • 缺点:与 Semaphore 相比,功能上略有限制,例如没有 Release(Int32) 方法,只能递增信号量一个单位。
  1. class Program
  2. {
  3. static SemaphoreSlim _semaphore = new SemaphoreSlim(2, 2); // Allow 2 threads to access the resource simultaneously
  4. static int _counter = 0;
  5. static void Main()
  6. {
  7. for (int i = 0; i < 5; i++)
  8. {
  9. new Thread(IncrementCounter).Start();
  10. }
  11. Console.ReadKey();
  12. }
  13. static void IncrementCounter()
  14. {
  15. _semaphore.Wait();
  16. _counter++;
  17. Console.WriteLine($"Counter: {_counter}");
  18. _semaphore.Release();
  19. }
  20. }
SemaphoreSlim

 

  1. lock:
    • 定义:

      lock 关键字用于在代码块级别实现互斥锁,确保共享资源在多线程环境中被安全访问。lock 关键字确保在同一时间只有一个线程可以访问共享资源,从而避免竞态条件和数据损坏。

      此外,lock 关键字在 C# 中是基于 Monitor 的概念实现的。lock 关键字在 C# 中是基于 Monitor 的概念实现的语法糖。当使用 lock 关键字时,它会自动获取对象的监视器锁(Monitor),并在代码块执行完毕后释放这个锁,以确保线程安全性。

    • 优点:
      1. 简单易用:lock 提供了一种简单的方式来实现线程同步,避免了开发人员手动管理锁的复杂性。
      2. 自动释放:lock 会自动释放锁,避免了忘记释放锁导致死锁的情况。
      3. 确保线程安全:通过使用 lock,可以确保共享资源在多线程环境下的安全访问。
    • 缺点:
      1. 潜在死锁:如果在锁内部发生了阻塞操作,可能会导致死锁情况的发生。
      2. 性能开销:频繁使用 lock 可能会导致性能开销,因为其他线程需要等待锁的释放。
      3. 可能引发竞态条件:如果 lock 的粒度过大,可能会导致竞态条件的发生,影响程序性能。
  1. class Program
  2. {
  3. static readonly object _lock = new object();
  4. static int _counter = 0;
  5. static void Main()
  6. {
  7. for (int i = 0; i < 5; i++)
  8. {
  9. new Thread(IncrementCounter).Start();
  10. }
  11. Console.ReadKey();
  12. }
  13. static void IncrementCounter()
  14. {
  15. lock (_lock)
  16. {
  17. _counter++;
  18. Console.WriteLine($"Counter: {_counter}");
  19. }
  20. }
  21. }
lock

 

原文链接:https://www.cnblogs.com/INetIMVC/p/18330485

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号