亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入多線程之:用Wait與Pulse模擬一些同步構(gòu)造的應(yīng)用詳解

 更新時(shí)間:2013年05月14日 15:02:59   作者:  
本篇文章是對用Wait與Pulse模擬一些同步構(gòu)造的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下

你可能在上篇文章中《深入多線程之:雙向信號與競賽的用法分析》注意到了這個(gè)模式:兩個(gè)Waiting 循環(huán)都要下面的構(gòu)造:

復(fù)制代碼 代碼如下:

lock(_locker)
{
        while(!_flag) Monitor.Wait(_locker);
        _flag = false;
}


在這里_flag被另一線程設(shè)置為true。這是,從作用上講,這里在模仿AutoResetEvent。如果我們將 _flag = false;去掉,那么我們就得到了一個(gè)基本的ManualResetEvent.

讓我們使用Wait和Pulse來為ManualResetEvent完成剩余的代碼吧。

復(fù)制代碼 代碼如下:

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,是因?yàn)榭赡苡泻芏嘧枞木€程。

如果在WaitOne方法中增加_signal=false就可以簡單的模擬AutoResetEvent.例如:

復(fù)制代碼 代碼如下:

void WaitOne()
        {
            lock (_locker)
            {
                while (!_signal) Monitor.Wait(_locker);
                _signal = false; //實(shí)現(xiàn)自動關(guān)閉功|能
            }
        }

然后在Set方法中,將PulseAll修改為Pulse

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

如果使用的是int類型的_signal 標(biāo)志,那么我們可以得到一個(gè)最基本的Semaphore.

Waiting Queues and PulseAll

當(dāng)多余一個(gè)線程在同一個(gè)對象上面等待的時(shí)候,一個(gè) “等待隊(duì)列(waiting queue)” 就形成了。

每一次調(diào)用Pulse都會釋放在”等待隊(duì)列”頭部的一個(gè)線程。下面的圖形象的展示了這一點(diǎn):

 

線程調(diào)用Monitor.Enter 進(jìn)入ReadyQueue. 等待獲取鎖,成功獲取鎖后,如果正常的執(zhí)行,那么之后會調(diào)用Monitor.Exit退出,

否則如果獲取了鎖之后發(fā)現(xiàn)需要等待其他的線程或者是其他阻塞條件,那么調(diào)用Wait方法,就進(jìn)入了等待隊(duì)列,

當(dāng)?shù)却木€程完成并調(diào)用Pulse后,處在WaitingQueue頭部的線程就被 Pulse了,等待CPU調(diào)度 。之后再次進(jìn)入Ready Queue,重新獲取鎖。


Countdown

借助Wait和Pulse,我們可以實(shí)現(xiàn)CountdownEvent的主要功能。例如:

復(fù)制代碼 代碼如下:

class Countdown
    {
        object _locker = new object();
        int _value; //使用_value來計(jì)數(shù)

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

        public void Singnal() { AddCount(-1); } //將計(jì)數(shù)減一

        public void AddCount(int amount)
        {
            lock (_locker)
            {
                _value += amount; //將計(jì)數(shù)增加或減少
                if (_value <= 0) Monitor.PulseAll(_locker);//如果value<=0,說明所有等待的任務(wù)都完成了。
            }
        }

        public void Wait()
        {
            lock (_locker)
            {
                //只要計(jì)數(shù) > 0 就等待。
                while (_value > 0)
                {
                    Monitor.Wait(_locker);
                }
            }
        }
}


這和我們上次的代碼幾乎一致,只是這次我們的阻塞條件基于一個(gè)整型_value標(biāo)志。

相關(guān)文章

最新評論