2

修飾子「volatile」に関するMicrosoftMSDNリファレンスページを見ていましたが、それらが提供するスニペットがスレッドの実行を完了するのを待つ方法について少し確信が持てませんでした。

これは単なるサンプルコードであり、スレッドは非常に迅速に完了したことを私は知っていますが、以下のコードは、スレッドを理解しようとしている開発者にとってはあまり良くないと思います。

マイクロソフトは実際に、コードに「タイトループ」を導入するコードスニペットを提示したと思います。このコードスニペットには(それほど)影響はないことを理解していますが、開発者がこのコードを取得して、もう少し集中的なマルチスレッドコードに使用しようとすると、「タイトループ」と見なされます。問題が発生しますか?

using System;
using System.Threading;
class Test
{
   public static int result;   
   public static volatile bool finished;
   static void Thread2() {
      result = 143;    
      finished = true; 
   }
   static void Main() {
      finished = false;
      // Run Thread2() in a new thread
      new Thread(new ThreadStart(Thread2)).Start();
      // Wait for Thread2 to signal that it has a result by setting
      // finished to true.
      for (;;) {
         if (finished) {
            Console.WriteLine("result = {0}", result);
            return;
         }
      }
   }
}

スニペットリファレンス: http ://msdn.microsoft.com/en-gb/library/aa645755(v = vs.71).aspx

上記の例で、この「タイトループ」状況を引き起こさないスレッドが終了するのを待つためのより良い方法は何でしょうか?

それとも、「タイトループ」は実際にはまったく導入されないのでしょうか。

スニペットの目的は「volatile」キーワードを示すことであるため、Thread.Join()を使用すると、スニペットがコンテキストから外れることに注意してください。

4

2 に答える 2

3

このスニペットは待機方法を示していません。これはvolatile、異なるスレッドからのフィールドへのアクセスを示しているだけです。

バックグラウンド スレッドを単純に待機するには、次のスニペットを使用できます。

AutoResetEvent autoEvent = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem((o) =>
                              {
                                   // do your stuff
                                   ((AutoResetEvent)o).Set();
                              }, autoEvent);
autoEvent.WaitOne();
于 2013-01-15T09:10:00.810 に答える
1

あなたが言うように、スレッドが終了するのを待つ最良の方法は、Thread.JoinまたはManualResetEventSlimイベントを使用することですが、どちらも揮発性のブール値を必要としません。

ループ内にThread.SpinWaitへの呼び出しを追加することで、例のコードを使用することができます。これは、プロセッサの枯渇を防ぐのに役立ちます。.Netのバージョン4で、MicrosoftはSpinWaitと呼ばれる構造体を追加しました。これはより効果的に使用できます。

これについての詳細は、Joseph Albahariによる「ThreadinginC#」にあります。

于 2013-01-15T09:13:24.693 に答える