码迷,mamicode.com
首页 > 其他好文 > 详细

WaitHandle学习笔记

时间:2017-12-13 00:02:27      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:原子操作   ide   执行   图片   共享   计数   got   子类   com   

信号量与互斥体              

互斥体(Mutex)是操作系统中一种独占访问共享资源的机制。它像一把所锁,哪个线程获取到互斥体的控制权,则可以访问共享的资源,或者执行处于受保护的代码。而其他的线程如果也想获取控制权,则需要要阻塞等待,知道拥有控制权的线程释放控制权。

信号量(Semaphore)是操作系统中协调多个线程访问共享资源的机制。他内部维护一个非负整数计数器。0表示不能再接受更多的共享访问请求,大于零的数值X表示最多还能接受X个线程的共享访问请求。而非负整数的操作只能通过wait()或者signal()来进行原子操作。signal将计数器加1; wait()将计数器减1,如果当前值为0则阻塞知道有其他线程调用signal。通过这种机制来实现最多X个线程访问共享资源。这种机制通常可以用来解决生产者和消费者问题。(假如产品队列最多能装X个产品,生产者相当于wait操作,消费者相当于signal操作)

.NET 中的WaitHandle           

技术分享图片

 在.Net Framework中有上图中三个子类。用来表示操作系统中的互斥体和信号量。

Mutex

Mutex是对操作系统中互斥体的包装,可以创建未命名的本地Mutex(只在当前进程有效),也可以创建命名的全局Mutex(操作系统有效,跨进程)。具体操作如下:

 

            var _mutex = new Mutex(false);
            new Task(() =>
            {
                _mutex.WaitOne();//获取mutex控制权
                Console.WriteLine("Got mutex signal. Thread Id:1");
                Thread.Sleep(1000);
                _mutex.ReleaseMutex();//释放mutex控制权
                Console.WriteLine("Release mutex signal, Thread Id:1");
            }).Start();

            new Task(() =>
            {
                _mutex.WaitOne();//获取mutex控制权,在thread 1释放之前,该调用会阻塞
                Console.WriteLine("Got mutex signal Thread id:2");
                Thread.Sleep(1000);
                _mutex.ReleaseMutex();
                Console.WriteLine("Release mutex signal, Thread Id:2");

            }).Start();

 

在操作Mutex时,系统会检查Thread Identity,只有获取Mutex控制权的线程才能释放控制权。

Semaphore

Semaphore是对操作系统中信号量的包装,同样也可以创建未命名的Semaphore(只在当前进程有效)和命名的全局Semaphore(操作系统有效,跨进程)具体操作如下:

但是在操作Semaphore时,和Mutex不一样,系统不会检查Thread Identity。任何线程都可以对Semaphore进行WaitOne()和Release()

 

            var _semaphore = new Semaphore(2, 2);//设置最大允许访问共享资源线程数为2

            new Task(() =>
            {
                for (int index = 0; index < 3; index++)
                {
                    _semaphore.WaitOne();//第三次调用该方法是会被阻塞,因为计数器为0.当其他线程调用Release后才能继续
                    Console.WriteLine("Got Semaphore Signal. Thread Id:" + Thread.CurrentThread.ManagedThreadId);
                }
            }).Start();

            new Task(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("Release Semaphore, Thread Id:" + Thread.CurrentThread.ManagedThreadId);
                _semaphore.Release();//计数器+1
            }).Start();

 

EventWaitHandle

这个类其实提供了和Mutex类似的线程之间同步,通知机制。它也能创建本地WaitHandle和全局WaitHandle。但是和Mutex又有区别:

  • 它内部其实维护了一个布尔类型变量来标示当前wait handle是否空闲:true表示空闲,可以被申请控制权; false则表示wait handle已经被线程持有控制权。(当调用WaitOne获取控制权时,如果内部标量为false,则阻塞知道其他线程将其Set为true.)而对该变量的操作只能通过Set()(将变量设为true),Reset()(将变量设为false)来进行原子操作。
  • EventWaitHandle并不提供独占操作,当内部变量为true时,所有线程的WaitOne操作都能获取到控制权,而不是只有一个能获取到(通过设置WaitHandle为AutoReset也可以实现)
  • 在操作EventWaitHandle时,系统也不会检查Thread Identity

具体操作如下:

            var _waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
       //这里指定AutoReset类型后,WaitOne调用获取到控制权后会同时将内部变量置为false,相当于调用Reset()
new Task(() => { _waitHandle.WaitOne(); Console.WriteLine("Got the signal, thread id:" + Thread.CurrentThread.ManagedThreadId); }).Start(); new Task(() => { _waitHandle.WaitOne(); Console.WriteLine("Got the signal, thread id:" + Thread.CurrentThread.ManagedThreadId); }).Start(); new Task(() => { Console.WriteLine("Set the signal, thread id:" + Thread.CurrentThread.ManagedThreadId); _waitHandle.Set(); }).Start();

 

WaitHandle学习笔记

标签:原子操作   ide   执行   图片   共享   计数   got   子类   com   

原文地址:http://www.cnblogs.com/Code-life/p/8030057.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!