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

首頁 > 編程 > C# > 正文

深入多線程之:雙向信號與競賽的用法分析

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

雙向信號和競賽(Two-Way Signaling and Races)
 
Monitor.Pulse方法的一個重要特性是它是異步執行的,這意味著調用pulse方法并不會阻塞自己等待Monitor.Pulse返回。如果任何一個線程在pulsed 對象上等待,它是不會阻塞的,換句話說,調用Monitor.Pulse對程序不會有什么作用,你可以認為Monitor.Pulse方法被忽略了。
這樣Pulse提供了一個單向通信:一個 pulsing線程悄悄的向一個waiting 線程發送信號。
Pulse并不會返回一個值來告訴你waiting線程是否收到信號。

但是有時候我們需要知道waiting線程是否受到信號,例如下面的例子:

復制代碼 代碼如下:

class Race
    {
        static readonly object _locker = new object();
        static bool  _go;
        public static void MainThread()
        {
            new Thread(SaySomething).Start();
            for (int i = 0; i < 5; i++)
            {
                lock (_locker)
                {
                    _go = true;
                    Monitor.PulseAll(_locker); //通知等待的隊列
                }
            }
        }
        static void SaySomething()
        {
            for (int i = 0; i < 5; i++)
            {
                lock (_locker)
                {
                    while (!_go) Monitor.Wait(_locker); //如果_go 為false,那么開始阻塞。
                    _go = false;
                    Console.WriteLine("Wassup?");
                }
            }
        }
    }

期待的輸出:
Wassup?
Wassup?
Wassup?
Wassup?
Wassup?

實際的輸出:

Wassup? (線程等待)
 
在SaySomething方法中,for循環執行到while,此時_go為false,所以Monitor.Wait開始等待。在MainThread中,for循環設置_go為true。然后PulseAll.但是PulseAll方法是異步的。
所以在SaySomething線程被喚醒前,mainThread中的for循環可能已經執行完畢。所以SaySomething方法中的第一個Wait線程收到消息詞是_go為true,所以往下執行,再次將_go字段設置為false。輸出”Wassup?”,但是下次循環由于_go為false,所以需要再次wait.所以實際的輸出打印了一個Wassup,然后開始等待。
我們需要主線程在每一次迭代中如果worker仍然在執行上一個任務,那么主線程阻塞。等到worker執行完畢,那么主線程恢復執行,然后執行迭代。

我們可以增加一個_ready 標志,從而控制主線程在設置_go 標志之前worker線程已經ready了。也就是說主線程在設置_go之前,會等待worker完成任務,然后等待worker將ready設為true,當worker將ready設置為true后,通過pulse來通知主線程。
復制代碼 代碼如下:

class Race
    {
        static readonly object _locker = new object();
        static bool _ready, _go;
        public static void MainThread()
        {
            new Thread(SaySomething).Start();
            for (int i = 0; i < 5; i++)
            {
                lock (_locker)
                {
                    while (!_ready) Monitor.Wait(_locker); //如果worker的ready為false,則等待worker。
                    _ready = false; //重置標志
                    _go = true;
                    Monitor.PulseAll(_locker);
                }
            }
        }
        static void SaySomething()
        {
            for (int i = 0; i < 5; i++)
            {
                lock (_locker)
                {
                    _ready = true; //將ready設置為true
                    Monitor.PulseAll(_locker); //通知主線程,worker已經ready了,可以執行任務了。
                    while (!_go) Monitor.Wait(_locker);
                    _go = false;
                    Console.WriteLine("Wassup?");
                }
            }
        }
    }

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 亚洲风情在线观看 | 91亚洲精品乱码久久久久久蜜桃 | 久久成人精品视频 | 日本免费一区二区三区 | 欧美一区不卡 | 亚洲精品影院 | 亚洲日本欧美日韩高观看 | 精品综合| 国精产品一区一区三区免费完 | 亚洲欧洲综合av | 亚洲高清免费 | 精品超碰 | 欧美视频二区 | 国产在线中文字幕 | 欧美一区二区大片 | 青青草97| 久久亚洲欧美日韩精品专区 | 亚洲一区成人 | 亚洲综合社区 | 国产偷录视频叫床高潮对白 | 日本狠狠操 | 国产99久| 中国特级黄色片 | 免费av在线网站 | 精品视频一区二区在线 | 91国自产区一二三区 | 欧美日韩天堂 | 久久亚洲精品裙底抄底 | 国产色99精品9i | 久久久久久久99精品免费观看 | 欧美精品久久久久久久宅男 | 欧美一级性 | 日韩欧美国产一区二区 | 午夜视频一区 | 蜜桃精品久久久久久久免费影院 | 国产精品视频免费播放 | 国内精品成人 | 精品国产一区二区三区久久久蜜月 | 日韩视频免费在线 | 日韩久久久久久 | 成人久久18免费网站图片 |