使用Mutex进行线程处理
Mutex就像一个C#锁(lock),但它可以跨多个进程工作。换句话说,Mutex可以是计算机范围的,也可以是应用程序范围的。
Mutex是一个同步原语,也可用于进程间同步。当两个或多个线程需要同时访问共享资源时,系统需要一个同步机制来确保一次只有一个线程使用该资源。Mutex是一个同步原语,它只允许对一个线程的共享资源进行独占访问。如果一个线程获得了一个Mutex,那么想要获取该Mutex的第二个线程将被挂起,直到第一个线程释放Mutex。
简而言之,互斥(“Mutex”)是一种机制,它充当一个标志,以防止两个线程同时执行一个或多个操作。您想要独占运行的整个操作称为关键部分或受保护部分。
关键部分是访问共享资源(数据结构或设备)的一段代码,但条件是一次只能有一个线程进入此部分。
现代编程语言天生就支持这一点。。在C#中,像下面这样简单:
实例化可从每个线程访问的新静态Mutex对象。
在每个线程中使用该对象的WaitOne()和ReleaseMutex()方法包装您想要在关键部分执行的任何代码
使用Mutex类,您可以调用WaitHandle.WaitOne方法加锁,用ReleaseMutex释放这个锁。关闭或dispose Mutex会自动释放它。与lock语句一样,Mutex只能从获取它的同一个线程中释放。
以下示例显示如何使用本地Mutex对象来同步对受保护资源的访问。
using System;
using System.Collections;
using System.Threading;
namespace Mutexclass
{
class Akshay { private static Mutex mutex = new Mutex(); private const int numhits = 1; private const int numThreads = 4; private static void ThreadProcess() { for (int i = 0; i < numhits; i++) { UseCsharpcorner(); } } private static void UseCsharpcorner() { mutex.WaitOne(); // Wait until it is safe to enter. Console.WriteLine("{0} has entered in the C_sharpcorner.com", Thread.CurrentThread.Name); // Place code to access non-reentrant resources here. Thread.Sleep(500); // Wait until it is safe to enter. Console.WriteLine("{0} is leaving the C_sharpcorner.com\r\n", Thread.CurrentThread.Name); mutex.ReleaseMutex(); // Release the Mutex. } static void Main(string[] args) { for (int i = 0; i < numThreads; i++) { Thread mycorner = new Thread(new ThreadStart(ThreadProcess)); mycorner.Name = String.Format("Thread{0}", i + 1); mycorner.Start(); } Console.Read(); } }
}
用Mutex来控制针对两个当前线程的共享资源
using System;
using System.Threading;
class MyCounter
{ public static int count = 0; public static Mutex MuTexLock = new Mutex();
}
class IncThread
{ public Thread th; public IncThread() { th = new Thread(this.GO); th.Start(); } void Go() { Console.WriteLine("IncThread is waiting for the mutex."); MyCounter.MuTexLock.WaitOne(); Console.WriteLine("IncThread acquires the mutex."); int num = 10; do { Thread.Sleep(50); MyCounter.count++; Console.WriteLine("In IncThread, MyCounter.count is " + MyCounter.count); num--; } while (num > 0); Console.WriteLine("IncThread releases the mutex."); MyCounter.MuTexLock.ReleaseMutex(); }
}
class DecThread
{ public Thread th; public DecThread() { th = new Thread(new ThreadStart(this.Go)); th.Start(); }| void Go()
| { Console.WriteLine("DecThread is waiting for the mutex."); MyCounter.MuTexLock.WaitOne(); Console.WriteLine("DecThread acquires the mutex."); int num = 10; do { Thread.Sleep(50); MyCounter.count--; Console.WriteLine("In DecThread, MyCounter.count is " + MyCounter.count); num--; } while (num > 0); Console.WriteLine("DecThread releases the mutex."); MyCounter.MuTexLock.ReleaseMutex(); }
}
class MainClass
{ public static void Main() {| IncThread myt1 = new IncThread(); DecThread myt2 = new DecThread(); myt1.thrd.Join(); myt2.thrd.Join(); Console.Read(); }
}
使用Mutex对象:WaitOne
重载的WaitOne()方法也接受TimeSpan对象,如果线程需要等待一段时间后执行的场景很有用。通常,当存在当两个或多个线程正在等待同一个互斥锁同时可用导致死锁的风险时使用此方法,。死锁听起来很糟糕,因为它可能导致应用程序互相等待导致而出现无响应或者超时。
using System;
using System.Threading;
namespace waitonmethod
{
class Akshay { private static int Runs = 0; static Mutex mutex = new Mutex(false, "RunsMutex");| public static void CountUp() { while (Runs < 10) { // acquire the mutex mutex.WaitOne(); int Temp = Runs; Temp++; Console.WriteLine(Thread.CurrentThread.Name + " " + Temp); Thread.Sleep(800); Runs = Temp; // release the mutex mutex.ReleaseMutex(); } } public static void Main() { Thread t2 = new Thread(new ThreadStart(CountUp)); t2.Name = "t2"; Thread t3 = new Thread(new ThreadStart(CountUp)); t3.Name = "t3"; t2.Start(); t3.Start(); Console.Read(); } }
}
得到互斥锁
互斥对象由线程拥有。当拥有时,它只能由一个线程拥有。当它由一个线程拥有时,在原始线程所有者释放它之前,其他线程不能拥有它。想要拥有互斥对象的线程调用互斥对象实例的WaitOne()方法。想要释放互斥锁的拥有线程调用ReleaseMutex()方法。
using System;
using System.Threading;
namespace ownamutex
{ class Akshay { public static void Main() { bool ownsMutex; using (Mutex mutex = new Mutex(true, "MutexExample", out ownsMutex)) { if (ownsMutex) { Console.WriteLine("Owned"); mutex.ReleaseMutex(); } else { Console.WriteLine("Another instance of this application " +" already owns the mutex named MutexExample."); } } Console.Read(); } }
}
命名Mutex
Mutex可以取别名,也可以默认。如果对互斥锁命名,那么它就有资格成为可以从多个进程访问的系统级别的互斥锁。如果互斥锁未命名,则它是一个匿名互斥锁,只能在创建互斥锁的进程内访问。
using System;
using System.Threading;
namespace Namingthread
{ class Akshay { public static void Main(string[] args) { string mutexName = "akshay"; Mutex m = new Mutex(false, mutexName); for (; ; ) { m.WaitOne(); Console.WriteLine("Have Mutex"); Console.WriteLine("Releasing"); m.ReleaseMutex(); } Console.Read(); } }
}
https://www.c-sharpcorner.com/UploadFile/1d42da/threading-with-mutex/
Akshay Teotia C# Corner
https://pdfs.semanticscholar.org/326a/0e09be808978c3bb9fdd006f3041dc0cbc13.pdf
Runtime Code Generation with JVM and CLR
使用Mutex进行线程处理相关推荐
- 线程同步 互斥量(mutex) Linux函数
线程同步: 线程的同步需要用到互斥量(mutex)用pthread_mutex_t类型表示. 互斥量(mutex)是一种简单的加锁的方法来控制对关心资源的访问.在同一时间只有一个线程掌握某个互斥上的锁 ...
- C#之:线程同步 Mutex类
Mutex(互斥锁): Mutex: 命名空间:System.Threading 一个同步基元,也可用于进程间同步.是.NET Framework 中提供跨多个线程,或多个进程同步访问的一个类.它非常 ...
- 线程编程常见API简介(中)
2019独角兽企业重金招聘Python工程师标准>>> 一.概述 在<线程编程常见API简介(上) >中讲述了有关线程创建过程中常用的 API 的使用方法,本节继续讲述有 ...
- 转载--线程同步机制及比较
转自:http://blog.csdn.net/eulb/article/details/2177500 先来回答第一个问题,线程实际主要应用于四个主要领域,当然各个领域之间不是绝对孤立的,他们有可能 ...
- 主线程和子线程的同步控制
一个线程的结束有两种途径,一种是象我们以下的样例一样.函数结束了.调用它的线程也就结束了.还有一种方式是通过函数pthread_exit来实现.另外须要说明的是,一个线程不能被多个线程等待,也就是说对 ...
- .NET 中使用 Mutex 进行跨越进程边界的同步 - walterlv
.NET 中使用 Mutex 进行跨越进程边界的同步 - walterlv 原文:.NET 中使用 Mutex 进行跨越进程边界的同步 - walterlv .NET 中使用 Mutex 进行跨越进程 ...
- 【C++ 语言】线程安全队列 ( 条件变量 | 线程调度 )
文章目录 I . 线程简单使用 II . 互斥锁 III . 条件变量 线程同步 IV . 完整代码示例 006_ThreadSafeQueue.h 006_ThreadSafeQueue.cpp S ...
- RAII实现的mutex资源类
为什么80%的码农都做不了架构师?>>> RAII,指的是Resource Acquisition is Initialization.即使用资源时对资源初始化,使用完毕进行自 ...
- 线程同步之——互斥量及死锁问题
互斥量:多个线程同时访问共享数据时可能会冲突,这跟信号的可重性是同样的问题.如 果两个线程都要把某个全局变量增加1,这个操作在某平台需要三条指令完成: 1. 从内存读变量值到寄存器 2. 寄存器的值加 ...
最新文章
- 几种经典的居中技巧(垂直和水平居中)
- 从硬盘上装xp手记(2005.8.14 )
- mysql修改表结构语句
- 百兆光纤收发器和千兆光纤收发器的区别
- RocketMQ 顺序消费只消费一次 坑
- vue一个页面用两个以上页面 时时刷新
- 利用DataSet、DataTable、DataView按照自定义条件过滤数据
- 如何能顺利往表中允许为null的字段插入null值(参数绑定)
- 判断当前是什么版本浏览器
- 新手在前期应该怎样发“外链”(4)之终级外链法
- 注:以前我的博客,因为丢了用户名和口令,无法使用,声明作废;现转于此。...
- 傅里叶变换与Matlab
- matlab识别水雷岩石,基于MATLAB的微弱信号检测方法仿真分析
- css缓慢执行hover
- js打开新窗口并且不被拦截
- 让你一遍就会的【单纯形法解线性规划最优】
- 晶联讯JLX12864G-086-PC-3S LCD显示屏 C51驱动代码
- vue-router 有哪几种导航钩子
- Haskell语言学习笔记(30)MonadCont, Cont, ContT
- docker个人容器云(基于阿里云)
热门文章
- ios12彻底关闭siri_Siri正在iOS 12中获取自定义语音操作
- 计算机启动程序bios_如何构建自己的计算机,第三部分:准备BIOS
- 如何在Photoshop中制作双曝光图像
- nodejs和Vue和Idea
- kotlin 初始化数组
- 微信小程序黑客马拉松即将开始,来做最酷的 Mini Program Creators!
- jsonp-反向代理-CORS解决JS跨域问题的个人总结
- C++ 对象的内 存布局(下)
- openssh登陆时提示服务器拒绝了密码
- 分布式云+dubbo+zookeeper+Springmvc整合