WaitHandle——使用Mutex

替代object加锁方式

   使用System.object对象作为线程同步的工具,建立了一个基本的锁机制,确保资源只能同时被一个线程所访问。

 

   但是这个对象不作任何其他用途,知识用于锁机制。

   如果有一个类型可以专注于为线程同步的锁机制和信号量机制提供服务,那么上面的代码就可以简化。

   .net中提供了更强大的system.threading.waithandle及其子类型,可以实现类似的效果。

     首先来看Mutex是如何取代object的:

//System.Threading.Mutex 用于锁机制,同一时刻只能有一个线程拥有它,只有等到该线程释放,其他线程才能持有它。
//因此,使用mutex可以完成和lock语句相同的功能。
//对于mutex来说,waitone方法为获取互斥体
        //(等待其他线程发出释放互斥体信号,如果没有任何其他线程占有互斥体,则调用waitone的线程获取到互斥体)

//releaseMutex方法则用于释放互斥体

namespace 使用Mutex
{
    class Program
    {
        private string called = "";
        private System.Threading.Mutex mtx = new System.Threading.Mutex();//使用互斥体

        static void Main(string[] args)
        {
            Program p = new Program();

            Thread.CurrentThread.Name = "main ";
            Thread worker = new Thread(p.ThreadEntry);
            worker.Name = "worker ";
            worker.Start();
            p.ThreadEntry();

        }

        void ThreadEntry() {

            this.mtx.WaitOne();//等待该实例收到信号为止,类似enter
            string name = Thread.CurrentThread.Name;
            called += string.Format("{0}:{1}",name ,DateTime .Now .Millisecond);
            Console.WriteLine(called);
            this.mtx.ReleaseMutex();  //释放互斥体:类是exit

        }
    }
}

Mutex带有参数的构造函数

Mutex的构造函数接受一个bool类型的参数,指示创建Mutex的线程是否立即持有它;
        相当于在mutex对象上调用waitone,其默认为false;

示例:

namespace Mutex有参数的构造函数
{
    class Program
    {

        public System.Threading.Mutex mtx = new System.Threading.Mutex(true);  //抢占:当前互斥体由主线程所有
        private string called = "";

        static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "main ";
            Program p = new Program();
            Thread worker = new Thread(p.ThreadEntry);
            worker.Name = "worker";
            worker.Start();
            Thread.Sleep(100);  //让worker线程先执行:目的是为了让worker线程先执行;
            p.ThreadEntry();

            #region 防止主线程一直占有资源

                //Thread.Sleep(100);
                //p.MainJob();

            #endregion
        }

        void ThreadEntry() {

            this.mtx.WaitOne();//worker线程在进入此方法后,会一直阻塞在这里;因为当前互斥体由主线程所有。
            string name = Thread.CurrentThread.Name;
            called += string.Format("{0} {1}",name ,DateTime .Now.Millisecond);
            Console.WriteLine(called);
            this.mtx.ReleaseMutex();

        }

        #region 防止主线程一直占有资源

           //void MainJob()
           // {
           //     //在此线程中,至调用了ReleaseMutex方法,;
           //    //尽管对主线程使用了sleep方法,但是由于主线程持有互斥体,worker线程仍然会等待主线程先执行万mainjob方法才会继续执行

           //     string name = Thread.CurrentThread.Name;
           //     called += string.Format("{0} {1}", name, DateTime.Now.Millisecond);
           //     Console.WriteLine(called);
           //     this.mtx.ReleaseMutex();

           // } 

        #endregion

    }
}

Mutex创建Singleton应用程序

    Mutex不仅提供跨线程的服务,还提供跨进程的服务。当在构造函数中为Mutex指定名称时,则会创建一个命名了的Mutex。

     其他线程创建mutex时,如果指定的名称相同,则返回同一个互斥体,不论该线程位于哪个进程或者应用程序域中。

     使用命名互斥体的一个例子是创建singleton应用程序,即只能打开一个实例的应用程序。

namespace Mutex创建singleton应用程序
{
    class Program
    {
        static void Main(string[] args)
        {
            string asm = Assembly.GetExecutingAssembly().GetName().Name;   //通过反射取值,获取到程序集的名称
            Mutex mtx = new Mutex(false ,asm);  //创建带有名称的互斥体

            if (!mtx.WaitOne (TimeSpan.FromMilliseconds (100)))   //该实例收到信号
            {
                Console .WriteLine ("{0} already running ",asm);  //提示该实例已经在运行了
                return ;  //直接return

            }

            //主线程第一次进入
            MainEntry(args);
            mtx.ReleaseMutex();//释放互斥体

        }

        static void MainEntry(string[] args) {

            Console.WriteLine("running~~~~~~~~~~~");
            Console.ReadLine();

        }
    }
}
时间: 2024-09-20 09:05:59

WaitHandle——使用Mutex的相关文章

多线程:C#线程同步lock,Monitor,Mutex,同步事件和等待句柄(中)

转自 http://www.cnblogs.com/freshman0216/archive/2008/07/30/1252345.html   本篇继续介绍WaitHandler类及其子类Mutex,ManualResetEvent,AutoResetEvent的用法..NET中线程同步的方式多的让人看了眼花缭乱,究竟该怎么去理解呢?其实,我们抛开.NET环境看线程同步,无非是执行两种操作:一是互斥/加锁,目的是保证临界区代码操作的"原子性":另一种是信号灯操作,目的是保证多个线程按

.Net线程问题解答

转自 http://www.cnblogs.com/yizhu2000/archive/2008/01/03/1011958.html 把遇到过的对.Net线程的一些问题和误解集中起来和大家分享,也希望大家能一起补充,热烈欢迎讨论 目录   基础篇 怎样创建一个线程 受托管的线程与 Windows线程 前台线程与后台线程 名为BeginXXX和EndXXX的方法是做什么用的 异步和多线程有什么关联 WinForm多线程编程篇 我的多线程WinForm程序老是抛出InvalidOperationE

[转载].Net线程问题解答

目录   基础篇 怎样创建一个线程 名为BeginXXX和EndXXX的方法是做什么用的 异步和多线程有什么关联 WinForm多线程编程篇 我的多线程WinForm程序老是抛出InvalidOperationException ,怎么解决? Invoke,BeginInvoke干什么用的,内部是怎么实现的 每个线程都有消息队列吗? 为什么Winform不允许跨线程修改UI线程控件的值 有没有什么办法可以简化WinForm多线程的开发 线程池 线程池的作用是什么? 所有进程使用一个共享的线程池,

一起谈.NET技术,.Net线程问题解答

基础篇 怎样创建一个线程 受托管的线程与 Windows线程 前台线程与后台线程 名为BeginXXX和EndXXX的方法是做什么用的 异步和多线程有什么关联 WinForm多线程编程篇 我的多线程WinForm程序老是抛出InvalidOperationException ,怎么解决? Invoke,BeginInvoke干什么用的,内部是怎么实现的 每个线程都有消息队列吗? 为什么Winform不允许跨线程修改UI线程控件的值 有没有什么办法可以简化WinForm多线程的开发 线程池 线程池

C#中Mutex对象用法分析_C#教程

本文实例讲述了C#中Mutex对象用法.分享给大家供大家参考,具体如下: C#语言有很多值得学习的地方,这里我们就来介绍C# Mutex对象,包括介绍控制好多个线程相互之间的联系等方面. 如何控制好多个线程相互之间的联系,不产生冲突和重复,这需要用到互斥对象,即:System.Threading 命名空间中的 Mutex 类. 我们可以把Mutex看作一个出租车,乘客看作线程.乘客首先等车,然后上车,最后下车.当一个乘客在车上时,其他乘客就只有等他下车以后才可以上车.而线程与C# Mutex对象

WaitHandle——使用ManualResetEvent

信号量机制     使用ManualResetEvent和AutoResetEvent都继承自EventWaitHandle(继承自waitHandle).EventWaitHandle对象有两个状态:收到信号(signaled)和未收到信号(nonsignaled):EventWaitHandle中的set和reset方法分别用于将eventwaitHandle对象的状态设为收到信号和未收到信号.      当EventWaitHandle未收到信号时,任何线程调用基类的wait方法都会被阻塞

难道分别在不同线程中的mutex.waitany(gms)与mutex.waitall(gms)不能够等待同一个mutex对象吗???

问题描述 usingSystem;usingSystem.Threading;///<summary>///问题是:Mutex.WaitAll(gMs)与线程3中的Mutex.WaitAny(gMs)在等待同一个Mutex对象时,///产生"由于出现被放弃的mutex,等待过程结束"异常;///</summary>publicclassMutexSample{//------定义两个互斥对象与自动重置事件对象----------staticMutexgM1;//

c# 线程同步: 详解lock,monitor,同步事件和等待句柄以及mutex

转自 http://www.cnblogs.com/xd125/archive/2007/12/12/992406.html 最近由于在准备Collection对象培训的PPT,因为涉及到SyncRoot的属性的讲解,所以对怎样在多线程应用程序中同步资源访问做了个总结:对于引用类型和非线程安全的资源的同步处理,有四种相关处理:lock关键字,监视器(Monitor), 同步事件和等待句柄, mutex类. Lock关键字    本人愚钝,在以前编程中遇到lock的问题总是使用lock(this)

WaitHandle——使用Semaphore

    semaphore也继承自waithandle,它用于锁机制,与Mutex不同的是,它允许指定数量的线程同时访问资源,在线程超过数量以后,则进行排队等待,直到之前的线程退出.     Semaphore很适合应用于web服务器这样的高并发场景,可以限制对资源访问的线程数.     Monitor与monitor都有一个锁持有者,而semaphore则不需要,因此通常将sempahore声明为静态的.      来看下面的示例: namespace 使用Semaphore { class