【问题标题】:Inform the compiler that a variable might be updated from another thread通知编译器变量可能会从另一个线程更新
【发布时间】:2015-12-27 20:36:54
【问题描述】:

这通常使用volatile 来完成。但对于longdouble,这是不可能的。

也许只是将其设为public 就足够了,然后编译器就知道它可以被另一个程序集使用并且不会“优化它”?这可以依靠吗?其他方式?

需要明确的是,我并不担心变量的并发读/写。只有一件事 - 它没有得到优化。 (就像在https://stackoverflow.com/a/1284007/939213 中一样。)

【问题讨论】:

  • 使用 Random 类,它会有更多可预测的行为。或者 System.Threading.Volatile
  • 你能展示一些你认为可以优化掉的代码吗?
  • 你打算如何“从另一个线程”更新这个变量?这并不是托管代码的真正工作方式。
  • @HansPassant 你能举例说明你的意思吗?我不明白。
  • @Batavia 它与问题相关联。你点击链接了吗?

标签: c# .net


【解决方案1】:

防止代码被删除的最好方法是使用代码。

如果您担心优化示例中的 while 循环

class Test  
{
   long foo;

   static void Main()
   {
      var test = new Test();

      new Thread(delegate() { Thread.Sleep(500); test.foo = 255; }).Start();

      while (test.foo != 255) ;
      Console.WriteLine("OK");
   }
}

你仍然可以通过修改你的 while 循环来使用 volatile 来做到这一点

volatile int temp;

//code skipped in this sample
while(test.foo != 255) { temp = (int)foo;}

现在假设您确定不会有任何线程安全问题。你正在使用你的 long foo 所以它不会被优化掉。而且你不在乎失去你的任何部分,因为你只是想保持它活着。

如果您执行此类操作,请确保非常清楚地标记您的代码。可能会写一个 VolatileLong 类来包装你的 long(和你的 volatile int),以便其他人了解你在做什么

其他线程安全工具(如锁)也会阻止代码删除。例如,编译器足够聪明,不会像这样在 sinleton 模式中删除 double if。

if (_instance == null) {
  lock(_lock) {
       if (_instance == null) { 
          _instance = new Singleton();
        }
   }
}
return _instance;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多