2

我正在查看有关修饰符“volatile”的 Microsoft MSDN 参考页面,并且有点不确定他们提供的代码段等待线程完成执行的方式。

我知道这只是示例代码,并且线程很快完成,但我相信下面的代码对于试图理解线程的开发人员来说并不是很好。

我相信微软实际上已经提供了一个代码片段,它将在代码中引入一个“紧密循环”。现在我很感激它不会影响这个代码片段(那么多),但是如果开发人员使用这个代码并尝试将它用于一些更密集的多线程代码,我会假设“紧密循环”会出现问题吗?

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 事件,但是这些都不需要volatile bool。

可以通过在循环中添加对Thread.SpinWait的调用来使用示例中的代码。这将有助于防止处理器饥饿。在 .Net 版本 4 中,Microsoft 添加了一个名为SpinWait的结构,可以更有效地使用它。

Joseph Albahari 的“C# 中的线程”中有更多关于此的信息

于 2013-01-15T09:13:24.693 回答