C#中Mutex对象用法分析

本文实例讲述了C#中Mutex对象用法。分享给大家供大家参考,具体如下:

C#语言有很多值得学习的地方,这里我们就来介绍C# Mutex对象,包括介绍控制好多个线程相互之间的联系等方面。

如何控制好多个线程相互之间的联系,不产生冲突和重复,这需要用到互斥对象,即:System.Threading 命名空间中的 Mutex 类。

我们可以把Mutex看作一个出租车,乘客看作线程。乘客首先等车,然后上车,最后下车。当一个乘客在车上时,其他乘客就只有等他下车以后才可以上车。而线程与C# Mutex对象的关系也正是如此,线程使用Mutex.WaitOne()方法等待C# Mutex对象被释放,如果它等待的C# Mutex对象被释放了,它就自动拥有这个对象,直到它调用Mutex.ReleaseMutex()方法释放这个对象,而在此期间,其他想要获取这个C# Mutex对象的线程都只有等待。

下面这个例子使用了C# Mutex对象来同步四个线程,主线程等待四个线程的结束,而这四个线程的运行又是与两个C# Mutex对象相关联的。

其中还用到AutoResetEvent类的对象,可以把它理解为一个信号灯。这里用它的有信号状态来表示一个线程的结束。

using System;
using System.Threading;
namespace ThreadExample
{
public class MutexSample
{
static Mutex gM1;
static Mutex gM2;
const int ITERS = 100;
static AutoResetEvent Event1 = new AutoResetEvent(false);
static AutoResetEvent Event2 = new AutoResetEvent(false);
static AutoResetEvent Event3 = new AutoResetEvent(false);
static AutoResetEvent Event4 = new AutoResetEvent(false);
public static void Main(String[] args)
{
Console.WriteLine("Mutex Sample ");
//创建一个Mutex对象,并且命名为MyMutex
gM1 = new Mutex(true,"MyMutex");
//创建一个未命名的Mutex 对象.
gM2 = new Mutex(true);
Console.WriteLine(" - Main Owns gM1 and gM2");
AutoResetEvent[] evs = new AutoResetEvent[4];
evs[0] = Event1; //为后面的线程t1,t2,t3,t4定义AutoResetEvent对象
evs[1] = Event2;
evs[2] = Event3;
evs[3] = Event4;
MutexSample tm = new MutexSample( );
Thread t1 = new Thread(new ThreadStart(tm.t1Start));
Thread t2 = new Thread(new ThreadStart(tm.t2Start));
Thread t3 = new Thread(new ThreadStart(tm.t3Start));
Thread t4 = new Thread(new ThreadStart(tm.t4Start));
t1.Start( );// 使用Mutex.WaitAll()方法等待一个Mutex数组中的对象全部被释放
t2.Start( );// 使用Mutex.WaitOne()方法等待gM1的释放
t3.Start( );// 使用Mutex.WaitAny()方法等待一个Mutex数组中任意一个对象被释放
t4.Start( );// 使用Mutex.WaitOne()方法等待gM2的释放
Thread.Sleep(2000);
Console.WriteLine(" - Main releases gM1");
gM1.ReleaseMutex( ); //线程t2,t3结束条件满足
Thread.Sleep(1000);
Console.WriteLine(" - Main releases gM2");
gM2.ReleaseMutex( ); //线程t1,t4结束条件满足
//等待所有四个线程结束
WaitHandle.WaitAll(evs);
Console.WriteLine(" Mutex Sample");
Console.ReadLine();
}
public void t1Start( )
{
Console.WriteLine("t1Start started, Mutex.WaitAll(Mutex[])");
Mutex[] gMs = new Mutex[2];
gMs[0] = gM1;//创建一个Mutex数组作为Mutex.WaitAll()方法的参数
gMs[1] = gM2;
Mutex.WaitAll(gMs);//等待gM1和gM2都被释放
Thread.Sleep(2000);
Console.WriteLine("t1Start finished, Mutex.WaitAll(Mutex[]) satisfied");
Event1.Set( ); //线程结束,将Event1设置为有信号状态
}
public void t2Start( )
{
Console.WriteLine("t2Start started, gM1.WaitOne( )");
gM1.WaitOne( );//等待gM1的释放
Console.WriteLine("t2Start finished, gM1.WaitOne( ) satisfied");
Event2.Set( );//线程结束,将Event2设置为有信号状态
}
public void t3Start( )
{
Console.WriteLine("t3Start started, Mutex.WaitAny(Mutex[])");
Mutex[] gMs = new Mutex[2];
gMs[0] = gM1;//创建一个Mutex数组作为Mutex.WaitAny()方法的参数
gMs[1] = gM2;
Mutex.WaitAny(gMs);//等待数组中任意一个Mutex对象被释放
Console.WriteLine("t3Start finished, Mutex.WaitAny(Mutex[])");
Event3.Set( );//线程结束,将Event3设置为有信号状态
}
public void t4Start( )
{
Console.WriteLine("t4Start started, gM2.WaitOne( )");
gM2.WaitOne( );//等待gM2被释放
Console.WriteLine("t4Start finished, gM2.WaitOne( )");
Event4.Set( );//线程结束,将Event4设置为有信号状态
}
}
}

更多关于C#相关内容感兴趣的读者可查看本站专题:《C#常见控件用法教程》、《WinForm控件用法总结》、《C#数据结构与算法教程》、《C#面向对象程序设计入门教程》及《C#程序设计之线程使用技巧总结》

希望本文所述对大家C#程序设计有所帮助。

(0)

相关推荐

  • c# 多线程编程 入门篇

    开始本应该是一篇洋洋洒洒的文字, 不过我还是提倡先做起来, 在尝试中去理解. 先试试这个: procedure TForm1.Button1Click(Sender: TObject);var i: Integer;begin for i := 0 to 500000 do begin Canvas.TextOut(10, 10, IntToStr(i)); end;end; 上面程序运行时, 我们的窗体基本是 "死" 的, 可以在你在程序运行期间拖动窗体试试... Delphi 为我

  • c#使用多线程的几种方式示例详解

    (1)不需要传递参数,也不需要返回参数 ThreadStart是一个委托,这个委托的定义为void ThreadStart(),没有参数与返回值. 复制代码 代码如下: class Program { static void Main(string[] args) { for (int i = 0; i < 30; i++) { ThreadStart threadStart = new ThreadStart(Calculate); Thread thread = new Thread(thr

  • c# winform 关闭窗体时同时结束线程实现思路

    前不久,做一个winform小程序,是给客户导数据用的.当时就发现调试的时候,线程有点问题,到某个点时就走不动了.但是运行确实没有问题的. 只是在关闭窗体后,资源管理器里,一大堆进程. 当时,客户急着用,小测了下,导出数据无误,进程就先不管了. 后来自己去查资料,发现只要在线程那里设置个属性 复制代码 代码如下: Thread th = new Thread(Excute); th.IsBackground = true;这样就解决问题了. 这个属性的意思就是把线程设置为后台线程. 然后关闭进程

  • C#子线程更新UI控件的方法实例总结

    本文实例总结了C#子线程更新UI控件的方法,对于桌面应用程序设计的UI界面控制来说非常有实用价值.分享给大家供大家参考之用.具体分析如下: 一般在winform C/S程序中经常会在子线程中更新控件的情况,桌面程序UI线程是主线程,当试图从子线程直接修改控件属性时会出现"从不是创建控件的线程访问它"的异常提示. 跨线程更新UI控件的常用方法有两种: 1.使用控件自身的invoke/BeginInvoke方法 2.使用SynchronizationContext的Post/Send方法更

  • C#使用Mutex简单实现程序单实例运行的方法

    本文实例讲述了C#使用Mutex简单实现程序单实例运行的方法.分享给大家供大家参考.具体如下: [STAThread] static void Main() { bool isAppRunning = false; System.Threading.Mutex mutex = new System.Threading.Mutex(true,System.Diagnostics.Process.GetCurrentProcess().ProcessName,out isAppRunning); i

  • c#多线程的应用全面解析

    1.使用多线程的几种方式 (1)不需要传递参数,也不需要返回参数 ThreadStart是一个委托,这个委托的定义为void ThreadStart(),没有参数与返回值. 复制代码 代码如下: class Program { static void Main(string[] args) { for (int i = 0; i < 30; i++) { ThreadStart threadStart = new ThreadStart(Calculate); Thread thread = n

  • c# mutex互斥量的深入解析

    互斥锁(Mutex) 互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程可以获取它. 互斥锁可适用于一个共享资源每次只能被一个线程访问的情况  函数: //创建一个处于未获取状态的互斥锁 Public Mutex(); //如果owned为true,互斥锁的初始状态就是被主线程所获取,否则处于未获取状态 Public Mutex(bool owned); 如果要获取一个互斥锁.应调用互斥锁上的WaitOne()方法,该方法继承于Thread.WaitHandle类 它处于等到状态直至所调

  • C#实现终止正在执行的线程

    本文实例讲述了C#实现终止正在执行的线程的实现方法,并针对一些容易出错的地方进行了深入分析,具体方法如下: 一般来说,很多人都会使用Abort方法来终止线程,其实这种做法并不可取!如果你的线程正在操作临界资源,很有可能会造成资源没有正确释放而出现死锁问题.正确的做法应该是使用标记来终止线程的执行. 基本思路是:定义一个用于描述"停止"信号的变量,在整个程序启动前,设置该变量为false.在线程中,循环判断该变量是否已经被设置为true,如果没有,则继续执行,否则就退出循环并释放资源,然

  • C#中的lock、Monitor、Mutex学习笔记

    线程:线程是进程的独立执行单元,每一个进程都有一个主线程,除了主线程可以包含其他的线程. 多线程的意义:多线程有助于改善程序的总体响应性,提高CPU的效率. 多线程的应用程序域是相当不稳定的,因为多个线程在同一时间内都能运行共享的功能模块.为了保护应用程序的资源不被破坏,为多线程程序提供了三种加锁的机制,分别是:Monitor类.Lock关键字和Mutex类. 1. lock lock实现的功能是:使后进入的线程不会中断当前的线程,而是等待当前线程结束后再继续执行. 应用: 复制代码 代码如下:

  • c#中多线程访问winform控件的若干问题小结

    我们在做winform应用的时候,大部分情况下都会碰到使用多线程控制界面上控件信息的问题.然而我们并不能用传统方法来解决这个问题,下面我将详细的介绍. 首先来看传统方法: 复制代码 代码如下: public partial class Form1 : Form     {        public Form1()        {            InitializeComponent();        } private void Form1_Load(object sender,

随机推荐