使用Mutex进行线程处理


640?wx_fmt=jpeg

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();  	
        }  	
    }  	
}

640?wx_fmt=png

用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();  	
    }  	
}

640?wx_fmt=png

使用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();  	
        }  	
    }  	
}


640?wx_fmt=png


得到互斥锁

互斥对象由线程拥有。当拥有时,它只能由一个线程拥有。当它由一个线程拥有时,在原始线程所有者释放它之前,其他线程不能拥有它。想要拥有互斥对象的线程调用互斥对象实例的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();  	
        }  	
    }  	
}

640?wx_fmt=png

命名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();  	
        }  	
   }  	
}


640?wx_fmt=png



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















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值