之前的博文也说到了如果多线程对于访问的公共资源操作都是原子操作,那么可以避免竞争条件。关于多线程的竞争可以百度。

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互斥量的使用的更多相关文章

  1. 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLock

    [源码下载] 重新想象 Windows 8 Store Apps (46) - 多线程之线程同步: Lock, Monitor, Interlocked, Mutex, ReaderWriterLoc ...

  2. Linux并发与同步专题 (4) Mutex互斥量

    关键词:mutex.MCS.OSQ. <Linux并发与同步专题 (1)原子操作和内存屏障> <Linux并发与同步专题 (2)spinlock> <Linux并发与同步 ...

  3. [一个经典的多线程同步问题]解决方案三:互斥量Mutex

    本篇通过互斥量来解决线程的同步,学习其中的一些知识. 互斥量也是一个内核对象,它用来确保一个线程独占一个资源的访问.互斥量与关键段的行为非常相似,并且互斥量可以用于不同进程中的线程互斥访问资源.使用互 ...

  4. 【Linux】Mutex互斥量线程同步的例子

    0.互斥量  Windows下的互斥量 是个内核对象,每次WaitForSingleObject和ReleaseMutex时都会检查当前线程ID和占有互斥量的线程ID是否一致. 当多次Wait**时就 ...

  5. C++多线程同步之Mutex(互斥量)

    原文链接: http://blog.csdn.net/olansefengye1/article/details/53086141 一.互斥量Mutex同步多线程 1.Win32平台 相关函数和头文件 ...

  6. 基元线程同步构造之 Mutes(互斥体)

    互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex)). 互斥体禁止多个线程同时进入受保护的代码“临界区”(critical section). 因 ...

  7. Linux 线程同步的三种方法(互斥锁、条件变量、信号量)

    互斥锁 #include <cstdio> #include <cstdlib> #include <unistd.h> #include <pthread. ...

  8. php Pthread 多线程 (三) Mutex 互斥量

    当我们用多线程操作同一个资源时,在同一时间内只能有一个线程能够对资源进行操作,这时就需要用到互斥量了.比如我们对同一个文件进行读写操作时. <?php class Add extends Thr ...

  9. mutex 互斥量

    有用参考:http://blog.csdn.net/yl2isoft/article/details/46003467 摘抄记录:using System.Threading; class Examp ...

随机推荐

  1. Python爬虫之selenium高级功能

    Python爬虫之selenium高级功能 原文地址 表单操作 元素拖拽 页面切换 弹窗处理 表单操作 表单里面会有文本框.密码框.下拉框.登陆框等. 这些涉及与页面的交互,比如输入.删除.点击等. ...

  2. Thinking in Annotation

    Thinking in Java这本书很久前就购买了,打算有时间看一下,因为自己的时间被自己安排的紧张,也没时间看书.黄师傅上次课程讲到了注解的使用和反射的使用,今天打算学习一下注解.该文章参考Thi ...

  3. bzoj4542 [Hnoi2016]大数 莫队+同余

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4542 题解 我们令 \(f_i\) 表示从 \(i\) 到 \(n\) 位组成的数 \(\bm ...

  4. Django【第4篇】:Django之模板继承

    jango框架之模板继承和静态文件配置 一.模板继承 目的是:减少代码的冗余 语法: {% block classinfo %} {% endblock %} 具体步骤: 1.创建一个base.htm ...

  5. Arduino通讯串口

    串口是Arduino与其它设备进行通信的接口 所有的Arduino控制板有至少一个串口(又称作为UART或USART).它通过0(RX)和1(TX)数字引脚经过串口转换芯片连接计算机USB端口与计算机 ...

  6. 【NOIP2016提高A组8.12】通讯

    题目 "这一切都是命运石之门的选择." 试图研制时间机器的机关SERN截获了中二科学家伦太郎发往过去的一条短信,并由此得知了伦太郎制作出了电话微波炉(仮). 为了掌握时间机器的技术 ...

  7. [洛谷P2567] SCOI2010 幸运数字

    问题描述 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的"幸运号码"是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是&quo ...

  8. jmeter测试https请求之导入证书

    jmeter测试https请求   公司最近在搞全站HTTPS改造,进一步提高网站的安全性,防止运营商劫持.那么,改造完成后,所有前后端的URL将全部为https. So ,研究下怎么用Jmeter访 ...

  9. 微信小程序-坑1-await-async

    VM45:1 thirdScriptError sdk uncaught third Error regeneratorRuntime is not defined ReferenceError: r ...

  10. SonarQube规则之漏洞类型

    漏洞类型: 1."@RequestMapping" methods should be "public"漏洞 阻断标注了RequestMapping是contr ...