a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C# > 正文

深入多線程之:用Wait與Pulse模擬一些同步構造的應用詳解

2020-01-24 03:19:46
字體:
來源:轉載
供稿:網友

你可能在上篇文章中《深入多線程之:雙向信號與競賽的用法分析》注意到了這個模式:兩個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都會釋放在”等待隊列”頭部的一個線程。下面的圖形象的展示了這一點:

 

線程調用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標志。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 久久久久久久久久久久久女国产乱 | 国产一区中文字幕 | 色狠狠一区 | 亚洲午夜电影 | 性处破╳╳╳高清欧美 | 久久综合狠狠综合久久综合88 | 亚洲毛片网 | 日本高清视频在线播放 | 国产精品久久久久久久久久久新郎 | 久久久日韩精品一区二区三区 | 久久久久中文字幕 | 成人日韩在线 | 成人免费视频视频在线观看 免费 | 国产精品一区二区三区99 | 久久一级 | 在线免费毛片 | 91精品蜜臀一区二区三区在线 | 精品国产高清一区二区三区 | 亚洲成人一区二区 | 免费视频爱爱太爽了 | 亚洲精品午夜国产va久久成人 | 久久99欧美 | 日日摸日日碰夜夜爽亚洲精品蜜乳 | 色婷婷精品国产一区二区三区 | 精品在线视频一区 | 国产精品久久久久久久午夜片 | 久久久成人精品视频 | 99精品视频久久精品视频 | 亚洲区一| 国产精品视频久久 | 亚洲欧美日韩在线一区二区 | 亚洲精品久久视频 | 91精品国产92| 国产精品视频播放 | 区一区二免费视频 | 国产精品美女久久久久aⅴ国产馆 | 超级黄色一级片 | 国产精品999 | 精品一二区 | 国产精品免费观看 | 日韩一区二区三区在线观看 |