c# Thread5——线程同步之基本原子操作。Mutex互斥量的使用
之前的博文也说到了如果多线程对于访问的公共资源操作都是原子操作,那么可以避免竞争条件。关于多线程的竞争可以百度。
1.执行最基本的原子操作
c#提供了一系列供我们使用的原子操作的方法和类型,比如我们的自增和自减操作。
看代码
class Program
{
private static int _count = ;
static void Main(string[] args)
{
var thread1 = new Thread(() =>
{
for(int i = ; i < ; i++)
{
Operation();
}
});
var thread2 = new Thread(() =>
{
for (int i = ; i < ; i++)
{
Operation();
}
});
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
Console.WriteLine(_count);
Console.Read();
}
public static void Operation()
{
//自增
_count ++;
_count--;
}
上面的代码还是会引起竞争条件问题,所以并不是线程安全的,我们可以使用c#提供的Interlocked进行自增,自减等操作,并且是原子性的。
对上面程序进行改动
private static int _count = ;
static void Main(string[] args)
{
var thread1 = new Thread(() =>
{
for(int i = ; i < ; i++)
{
Operation();
}
});
var thread2 = new Thread(() =>
{
for (int i = ; i < ; i++)
{
Operation();
}
});
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
Console.WriteLine(_count);
Console.Read();
}
public static void Operation()
{
//自增
Interlocked.Increment(ref _count);
Interlocked.Decrement(ref _count);
}
结果就是正确的了。
2.Metux类(互斥量)
Mutex是一种原始的在线程同步方式,它只对一个线程授予共享资源的独占访问,并且它是操作系统全局的,所以它更大的场景用于不同程序之间多线程的同步
它的几个构造方法在上图中。
Mutex():这是比较特殊的,用的很少的构造方法,因为之前说Mutex是一个操作系统全局的互斥量,但是需要根据名字来使用,这种构造方法是匿名的,所以可以称作局部互斥量。
Mutex(bool initiallyOwned):传入的bool值表示创建者是否立刻拥有该互斥量
Mutex(bool initiallyOwned,string name):与上面的区别就是拥有名字,可以在去他程序中被使用。
Mutex(bool initiallyOwned,string name,out bool createNew):第三个out参数用于表明是否获得了初始的拥有权。这个构造函数应该是我们在实际中使用较多的。
Mutex(bool initiallyOwned,string name,out bool createNew,MuteSecurity muteSecurity):第四个参数是对于Mutex的一些安全设置,详见MSDN
说这么多我们先来一个例子来看看如何使用Mutex
private static readonly string MutexName = "GLOBAL_MUTEX";
static void Main(string[] args)
{
var thread = new Thread(() => { Operations(); });
thread.Start();
Operations(); Console.ReadLine();
} public static void Operations()
{
bool result;
using (var mutex = new Mutex(false, MutexName,out result))
{
try
{
if (mutex.WaitOne(TimeSpan.FromSeconds(), false))
{
Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId} Instance is running");
Thread.Sleep();
Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId} Instance is Exiting");
}
}
catch
{ }
finally
{
mutex.ReleaseMutex();
} }
}
这段代码其实就是看主线程和子线程谁先拿到互斥量,就可以先执行,另外一个线程就会等待它执行完再去执行。所以结果如下。
我们稍微改动一下代码。
private static readonly string MutexName = "GLOBAL_MUTEX";
static void Main(string[] args)
{
var thread = new Thread(() => { Operations(); });
thread.Start();
Operations(); Console.ReadLine();
} public static void Operations()
{
bool result;
using (var mutex = new Mutex(false, MutexName,out result))
{
try
{
if (mutex.WaitOne(TimeSpan.FromSeconds(), false))
{
Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId} Instance is running");
Thread.Sleep();
Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId} Instance is Exiting");
mutex.ReleaseMutex();
}
else
{
Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId} Instance is waitting out of time");
}
}
catch
{
Console.WriteLine("error");
}
finally
{ } }
}
增加一点时间延迟,因为我们设置了5s的等待,但是主体时间超过6s,所以必将会有线程等待超时。
那么可能会有人问了,那他和上一节的monitor到底有何区别?其实最大的区别也提到过了,就是它是操作系统全局的。具体细节可以参考园子里这篇文章,写的比我详细很多。
https://www.cnblogs.com/suntp/p/8258488.html
最后就是因为Mutex对象是操作系统全局的,一定要正确关闭释放它。
c# Thread5——线程同步之基本原子操作。Mutex互斥量的使用的更多相关文章
- 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLock
[源码下载] 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLoc ...
- Linux并发与同步专题 (4) Mutex互斥量
关键词:mutex.MCS.OSQ. <Linux并发与同步专题 (1)原子操作和内存屏障> <Linux并发与同步专题 (2)spinlock> <Linux并发与同步 ...
- [一个经典的多线程同步问题]解决方案三:互斥量Mutex
本篇通过互斥量来解决线程的同步,学习其中的一些知识. 互斥量也是一个内核对象,它用来确保一个线程独占一个资源的访问.互斥量与关键段的行为非常相似,并且互斥量可以用于不同进程中的线程互斥访问资源.使用互 ...
- 【Linux】Mutex互斥量线程同步的例子
0.互斥量 Windows下的互斥量 是个内核对象,每次WaitForSingleObject和ReleaseMutex时都会检查当前线程ID和占有互斥量的线程ID是否一致. 当多次Wait**时就 ...
- C++多线程同步之Mutex(互斥量)
原文链接: http://blog.csdn.net/olansefengye1/article/details/53086141 一.互斥量Mutex同步多线程 1.Win32平台 相关函数和头文件 ...
- 基元线程同步构造之 Mutes(互斥体)
互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex)). 互斥体禁止多个线程同时进入受保护的代码“临界区”(critical section). 因 ...
- Linux 线程同步的三种方法(互斥锁、条件变量、信号量)
互斥锁 #include <cstdio> #include <cstdlib> #include <unistd.h> #include <pthread. ...
- php Pthread 多线程 (三) Mutex 互斥量
当我们用多线程操作同一个资源时,在同一时间内只能有一个线程能够对资源进行操作,这时就需要用到互斥量了.比如我们对同一个文件进行读写操作时. <?php class Add extends Thr ...
- mutex 互斥量
有用参考:http://blog.csdn.net/yl2isoft/article/details/46003467 摘抄记录:using System.Threading; class Examp ...
随机推荐
- 理解 OutOfMemoryError 异常
OutOfMemoryError 异常应该可以算得上是一个非常棘手的问题.JAVA 的程序员不用像苦逼的 C 语言程序员手动地管理内存,JVM 帮助他们分配内存,释放内存.但是当遇到内存相关的问题,就 ...
- ab压测
安装:yum install -y httpd-tools 验证:ab -V ab -help:-n requests 要执行请求总数,默认会执行一个请求 -c concurrency 一次执行多个请 ...
- MapReduce单机提交(待稿)
MR 提交方式源码 提交方式: 1,开发-> jar -> 上传到集群中的某一个节点 -> hadoop jar ooxx.jar ooxx in out 2,嵌入[linux,wi ...
- CRMEasy知识库点击无法弹出窗体问题
丢失控件 MSDATLST.OCX 将此控件放在路径下 C:\Windows\System32 并进行注册,具体方法为: 打开控件方式选择 C:\Windows\System32\reg ...
- redis-5.0.5 集群部署
之前写过一套基于redis-4.0.6版本的测试集群部署 https://www.cnblogs.com/mrice/p/10730309.html 最近生产环境需要部署一套redis-5.0.5版本 ...
- java String源码浅出
1.public char charAt(int index) 返回指定索引处的 char 值. 源码: =====================String.class============== ...
- python 7行代码实现微信机器人自动回复
首先 需要去 图灵 网站注册 获取api_key 先上代码 from wxpy import * bot = Bot() tuling = Tuling(api_key='你的api_key') @b ...
- 【leetcode】838. Push Dominoes
题目如下: 解题思路:本题题目中有一点要求很关键,“we will consider that a falling domino expends no additional force to a fa ...
- js 文件下载 兼容ie
前置条件:后台接口返回二进制流文件 一.设置前端请求的的 responseType: 'blob' 二.接收请求数据并调用下载 var content = res.data // 接口返回的二进制流v ...
- LTM_本地流量管理(一)
基本元素及概念 Node:节点,即服务器的IP地址. Member:成员,即一个服务,用IP+端口表示. Pool:池:一个或多个Member的逻辑分组,一个Pool表示一个应用,每个Pool都有自己 ...