手机
当前位置:查字典教程网 >编程开发 >C#教程 >深入多线程之:用Wait与Pulse模拟一些同步构造的应用详解
深入多线程之:用Wait与Pulse模拟一些同步构造的应用详解
摘要:你可能在上篇文章中《深入多线程之:双向信号与竞赛的用法分析》注意到了这个模式:两个Waiting循环都要下面的构造:复制代码代码如下:loc...

你可能在上篇文章中《深入多线程之:双向信号与竞赛的用法分析》注意到了这个模式:两个Waiting 循环都要下面的构造:

复制代码 代码如下:

lock(_locker)

{

while(!_flag) Monitor.Wait(_locker);

_flag = false;

}

在这里_flag被另一线程设置为true。这是,从作用上讲,这里在模仿AutoResetEvent。如果我们将 _flag = false;去掉,那么我们就得到了一个基本的ManualResetEvent.

让我们使用Wait和Pulse来为ManualResetEvent完成剩余的代码吧。

复制代码 代码如下:

readonly object _locker = new object();

bool _signal;

void WaitOne()

{

lock (_locker)

{

while (!_signal) Monitor.Wait(_locker);

}

}

void Set()

{

lock (_locker) { _signal = true; Monitor.PulseAll(_locker); }

}

void Reset() { lock (_locker) _signal = false; }

在这里使用PulseAll,是因为可能有很多阻塞的线程。

如果在WaitOne方法中增加_signal=false就可以简单的模拟AutoResetEvent.例如:

复制代码 代码如下:

void WaitOne()

{

lock (_locker)

{

while (!_signal) Monitor.Wait(_locker);

_signal = false; //实现自动关闭功|能

}

}

然后在Set方法中,将PulseAll修改为Pulse

Lock(_locker) {_signal = true; Monitor.Pulse(_locker);}

如果使用的是int类型的_signal 标志,那么我们可以得到一个最基本的Semaphore.

Waiting Queues and PulseAll

当多余一个线程在同一个对象上面等待的时候,一个 “等待队列(waiting queue)” 就形成了。

每一次调用Pulse都会释放在”等待队列”头部的一个线程。下面的图形象的展示了这一点:

深入多线程之:用Wait与Pulse模拟一些同步构造的应用详解1

线程调用Monitor.Enter 进入ReadyQueue. 等待获取锁,成功获取锁后,如果正常的执行,那么之后会调用Monitor.Exit退出,

否则如果获取了锁之后发现需要等待其他的线程或者是其他阻塞条件,那么调用Wait方法,就进入了等待队列,

当等待的线程完成并调用Pulse后,处在WaitingQueue头部的线程就被 Pulse了,等待CPU调度 。之后再次进入Ready Queue,重新获取锁。

Countdown

借助Wait和Pulse,我们可以实现CountdownEvent的主要功能。例如:

复制代码 代码如下:

class Countdown

{

object _locker = new object();

int _value; //使用_value来计数

public Countdown() { }

public Countdown(int initialCount) { _value = initialCount; }

public void Singnal() { AddCount(-1); } //将计数减一

public void AddCount(int amount)

{

lock (_locker)

{

_value += amount; //将计数增加或减少

if (_value <= 0) Monitor.PulseAll(_locker);//如果value<=0,说明所有等待的任务都完成了。

}

}

public void Wait()

{

lock (_locker)

{

//只要计数 > 0 就等待。

while (_value > 0)

{

Monitor.Wait(_locker);

}

}

}

}

这和我们上次的代码几乎一致,只是这次我们的阻塞条件基于一个整型_value标志。

【深入多线程之:用Wait与Pulse模拟一些同步构造的应用详解】相关文章:

使用异步方式调用同步方法(实例详解)

c#实现隐藏与显示任务栏的方法详解

深入多线程之:Reader与Write Locks(读写锁)的使用详解

深入分析C#中WinForm控件之Dock顺序调整的详解

异步/多线程/任务/并行编程之一:如何选择合适的多线程模型?

解析使用enumerator模式简化异步操作的详解

深入反射生成数组的详解

深入多线程之:深入分析Interlocked

基于动态修改App.Config与web.Config的使用详解

基于一个应用程序多线程误用的分析详解

精品推荐
分类导航