C# 编程中互斥锁的使用

devtools/2024/10/18 22:37:14/

C# 中的互斥锁

互斥锁是 C# 中使用的同步原语,用于控制多个线程或进程对共享资源的访问。其目的是确保在任何给定时间只有一个线程或进程可以获取互斥锁,从而提供互斥。

C# 中互斥锁的优点

可以使用互斥锁 (Mutex) 并享受其带来的好处。

1. 共享资源的独占访问

  • 场景:多个线程或进程需要独占访问共享资源(例如文件、数据库或硬件设备)的情况。
  • 示例:考虑一个多线程应用程序,其中多个线程需要同时写入共享日志文件。
  • 好处: 利用互斥锁,可以保证一次只有一个线程或进程可以访问资源,从而防止数据损坏或竞争条件。

2.跨进程同步

  • 场景:不同进程中运行的线程之间需要同步。
  • 示例:协调多个进程对共享内存映射文件的访问。
  • 好处:互斥锁可以被命名并在整个系统范围内使用,从而实现跨进程边界的同步。

3. 关键部分保护

  • 场景:代码的关键部分需要防止被多个线程并发执行的情况。
  • 示例:考虑一个缓存实现,其中添加或删除项目必须是线程安全的。
  • 好处:通过使用互斥锁,它有助于对关键部分的访问进行序列化,确保一次只有一个线程执行受保护的代码,从而避免竞争条件。

4. 资源池化

  • 场景:管理对有限资源池(例如数据库连接或网络套接字)的访问时。
  • 示例:多个线程竞争可用连接的连接池。
  • 好处:可以使用互斥锁 (Mutex) 来控制对池的访问,从而保证同时使用的用户数量不超过池的容量。

5.避免死锁

  • 场景:在多个同步原语一起使用以防止发生死锁的情况下。
  • 示例:实现一个需要原子锁定多个资源的事务系统。
  • 好处:互斥锁可以参与死锁避免策略,有助于防止死锁情况的发生。

互斥锁的实现

步骤1.

使用Xaml View测试所有情况。

<Window x:Class="MutexExample.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:MutexExample"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid><StackPanel Orientation="Vertical"><Button x:Name="BtnSR" Height="30" Content="Shared Resource" Margin="10" Click="BtnSR_Click"/><Button x:Name="BtnCPS" Height="30" Content="Cross-Process Synchronization" Margin="10" Click="BtnCPS_Click"/><Button x:Name="BtnCSP" Height="30" Content="Critical Section Protection" Margin="10" Click="BtnCSP_Click"/><Button x:Name="BtnRP" Height="30" Content="Resource Pooling" Margin="10" Click="BtnRP_Click"/><Button x:Name="BtnDLA" Height="30" Content="Deadlock Avoidance" Margin="10" Click="BtnDLA_Click"/></StackPanel></Grid>
</Window>

后端编程

using System;
using System.Threading;
using System.Windows;namespace MutexExample
{public partial class MainWindow : Window{Mutex mutex = new Mutex();static int availableResources = 3;public MainWindow(){InitializeComponent();}private void SharedResourceAccess(object id){mutex.WaitOne(); // Acquire the mutextry{Console.WriteLine($"Thread {id} is accessing the shared resource...");// Simulate some workThread.Sleep(2000);}finally{mutex.ReleaseMutex(); // Release the mutex}}private void BtnSR_Click(object sender, RoutedEventArgs e){// Create multiple threads accessing the shared resourcefor (int i = 0; i < 5; i++){Thread thread = new Thread(SharedResourceAccess);thread.Start(i);}}private void BtnCPS_Click(object sender, RoutedEventArgs e){// Acquire the mutexif (mutex.WaitOne(TimeSpan.FromSeconds(5))){try{Console.WriteLine("Process 1 has acquired the mutex.");Console.ReadLine(); // Hold the mutex until Enter is pressed}finally{mutex.ReleaseMutex(); // Release the mutex}}else{Console.WriteLine("Process 1 failed to acquire the mutex.");}}private void CriticalSectionAccess(object id){mutex.WaitOne(); // Acquire the mutextry{Console.WriteLine($"Thread {id} is executing the critical section...");// Simulate some workThread.Sleep(2000);}finally{mutex.ReleaseMutex(); // Release the mutex}}private void BtnCSP_Click(object sender, RoutedEventArgs e){// Create multiple threads accessing a critical sectionfor (int i = 0; i < 5; i++){Thread thread = new Thread(CriticalSectionAccess);thread.Start(i);}}private void ResourceAccess(object id){mutex.WaitOne(); // Acquire the mutextry{if (availableResources > 0){availableResources--;Console.WriteLine($"Thread {id} acquired a resource. Remaining resources: {availableResources}");// Simulate some workThread.Sleep(2000);availableResources++;}else{Console.WriteLine($"Thread {id} could not acquire a resource. No resources available.");}}finally{mutex.ReleaseMutex(); // Release the mutex}}private void BtnRP_Click(object sender, RoutedEventArgs e){// Create multiple threads to access the resource poolfor (int i = 0; i < 5; i++){Thread thread = new Thread(ResourceAccess);thread.Start(i);}}private void BtnDLA_Click(object sender, RoutedEventArgs e){Thread thread1 = new Thread(Thread1);Thread thread2 = new Thread(Thread2);thread1.Start();thread2.Start();thread1.Join();thread2.Join();}private Mutex mutex1 = new Mutex();private Mutex mutex2 = new Mutex();private void Thread1(){mutex1.WaitOne();Console.WriteLine("Thread 1 acquired mutex1");Thread.Sleep(1000);mutex2.WaitOne();Console.WriteLine("Thread 1 acquired mutex2");mutex2.ReleaseMutex();mutex1.ReleaseMutex();}private void Thread2(){mutex2.WaitOne();Console.WriteLine("Thread 2 acquired mutex2");Thread.Sleep(1000);mutex1.WaitOne();Console.WriteLine("Thread 2 acquired mutex1");mutex1.ReleaseMutex();mutex2.ReleaseMutex();}}
}

http://www.ppmy.cn/devtools/57882.html

相关文章

ssrf结合redis未授权getshell

目录 漏洞介绍 SSRF Redis未授权 利用原理 环境搭建 利用过程 rockylinux cron计划任务反弹shell 写公钥免密登录 ubuntu 写公钥免密登录 漏洞介绍 SSRF SSRF&#xff08;server side request forgrey&#xff09;服务端请求伪造&#xff0c;因后端未过滤用户输入&…

深度学习之半监督学习:一文梳理目标检测中的半监督学习策略

什么是半监督目标检测&#xff1f; 传统机器学习根据训练数据集中的标注情况&#xff0c;有着不同的场景&#xff0c;主要包括&#xff1a;监督学习、弱监督学习、弱半监督学习、半监督学习。由于目标检测任务的特殊性&#xff0c;在介绍半监督目标检测方法之前&#xff0c;我…

cpp struct json相互转换

使用nlohmann的库 “安装” 把include下载到本地可以include的位置 demo 需要再struct和class中实现to_json()和from_json()函数。 貌似cpp20可以通过反射无需手动编写to_json()和from_json()&#xff0c;这里不做展开 #include <iostream> #include "nlohmann/…

TCP一定可靠吗

背景 公司某个服务发送TCP报文后,得到的响应是非预期数据 原因竟然是:TCP包的 payload 数据某个bit位被翻转,但是 checksum 的值一样,错误的包被分发给了上层服务 Checksum介绍 IP 头有自己的 Checksum,TCP、UDP 也有自己的 Checksum,分别校验不同部分的数据 IP 头的 …

在linux系统centos上面安装php7gmp扩展

ps:在ubuntu上面安装gmp(最简单) $ sudo apt-get install php7.0-gmp然后再php.ini添加extensionphp_gmp.so <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<…

1.Python学习笔记

一、环境配置 1.Python解释器 把程序员用编程语言编写的程序&#xff0c;翻译成计算机可以执行的机器语言 安装&#xff1a; 双击Python3.7.0-选择自定义安装【Customize installation】-勾选配置环境变量 如果没有勾选配置环境变量&#xff0c;输入python就会提示找不到命令…

什么是数据分析?数据分析如何创造企业发挥价值?

数据分析是在具体的业务场景下&#xff0c;如何借助工具&#xff0c;通过数据解决问题的思路 数据底层的四大优势 1.可反复读取和使用 2.客观 3.量化 4.机器可处理 使用数据指导业务&#xff0c;基于数据量化生产 只要是基于量化的信息提升生产力&#xff0c;就是数据分析&a…

关于C#如何在打开新界面时,将旧界面的指定数据发送到新界面的方法

关于C#如何在打开新界面时&#xff0c;将旧界面的指定数据发送到新界面的方法 1.主界面代码1.打开的新界面代码 1.主界面代码 private void Btn_Click(object sender, RoutedEventArgs e) {string value1 "NULL";string value2 "NULL";string value3 &…