C#的多线程机制探索(5)
2007-04-03 15:54
五、互斥对象
——
更加灵活的同步方式
有 时候你会觉得上面介绍的方法好像不够用,对,我们解决了代码和资源的同步问题,解决了多线程自动化管理和定时触发的问题,但是如何控制多个线程相互之间的 联系呢?例如我要到餐厅吃饭,在吃饭之前我先得等待厨师把饭菜做好,之后我开始吃饭,吃完我还得付款,付款方式可以是现金,也可以是信用卡,付款之后我才 能离开。分析一下这个过程,我吃饭可以看作是主线程,厨师做饭又是一个线程,服务员用信用卡收款和收现金可以看作另外两个线程,大家可以很清楚地看到其中 的关系 —— 我吃饭必须等待厨师做饭,然后等待两个收款线程之中任意一个的完成,然后我吃饭这个线程可以执行离开这个步骤,于是我吃饭才算结束了。事实上,现实中有着比这更复杂的联系,我们怎样才能很好地控制它们而不产生冲突和重复呢? 这种情况下,我们需要用到互斥对象,即 System.Threading 命名空间中的 Mutex 类。大家一定坐过出租车吧,事实上我们可以把 Mutex 看作一个出租车,那么乘客就是线程了,乘客首先得等车,然后上车,最后下车,当一个乘客在车上时,其他乘客就只有等他下车以后才可以上车。而线程与 Mutex 对象的关系也正是如此,线程使用 Mutex.WaitOne() 方法等待 Mutex 对象被释放,如果它等待的 Mutex 对象被释放了,它就自动拥有这个对象,直到它调用 Mutex.ReleaseMutex() 方法释放这个对象,而在此期间,其他想要获取这个 Mutex 对象的线程都只有等待。 下面这个例子使用了 Mutex 对象来同步四个线程,主线程等待四个线程的结束,而这四个线程的运行又是与两个 Mutex 对象相关联的。其中还用到 AutoResetEvent 类的对象,如同上面提到的 ManualResetEvent 对象一样,大家可以把它简单地理解为一个信号灯,使用 AutoResetEvent.Set() 方法可以设置它为有信号状态,而使用 AutoResetEvent.Reset() 方法把它设置为无信号状态。这里用它的有信号状态来表示一个线程的结束。
|