加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

以下C#代码线程是否安全?

发布时间:2020-12-15 18:15:58 所属栏目:百科 来源:网络整理
导读:我正在尝试学习C#中的线程.今天我在 http://www.albahari.com/threading/播种以下代码: class ThreadTest{ bool done; static void Main() { ThreadTest tt = new ThreadTest(); // Create a common instance new Thread (tt.Go).Start(); tt.Go(); } // No
我正在尝试学习C#中的线程.今天我在 http://www.albahari.com/threading/播种以下代码:
class ThreadTest
{
  bool done;

  static void Main()
  {
    ThreadTest tt = new ThreadTest();   // Create a common instance
    new Thread (tt.Go).Start();
    tt.Go();
  }

  // Note that Go is now an instance method
  void Go() 
  {
     if (!done) { done = true; Console.WriteLine ("Done"); }
  }
}

在Java中,除非将“完成”定义为volatile,否则代码将不安全. C#内存模型如何处理这个问题?

伙计们,谢谢大家的答案.非常感激.

解决方法

好吧,有明显的竞争条件,他们都可以看到做错和执行if身体 – 无论记忆模型如何都是如此.完成volatile并不会解决这个问题,也不会在Java中修复它.

但是,是的,在一个线程中进行的更改可能会发生,但在另一个线程中不可见.这取决于CPU架构等.作为我的意思的一个例子,考虑这个程序:

using System;
using System.Threading;

class Test
{
    private bool stop = false;

    static void Main()
    {
        new Test().Start();
    }

    void Start()
    {
        new Thread(ThreadJob).Start();
        Thread.Sleep(500);
        stop = true;
    }

    void ThreadJob()
    {
        int x = 0;
        while (!stop)
        {
            x++;
        }
        Console.WriteLine("Counted to {0}",x);
    }
}

虽然在我当前的笔记本电脑上这已经终止,我已经使用了其他机器,其中几乎完全相同的代码将永远运行 – 它永远不会“看到”更改停止在第二个线程中.

基本上,我试图避免编写无锁代码,除非它使用由真正了解其内容的人提供的更高级别的抽象 – 比如.NET 4中的Parallel Extensions.

有一种方法可以使用Interlocked使这段代码无锁,并且很容易纠正.例如:

class ThreadTest
{
  int done;

  static void Main()
  {
    ThreadTest tt = new ThreadTest();   // Create a common instance
    new Thread (tt.Go).Start();
    tt.Go();
  }

  // Note that Go is now an instance method
  void Go() 
  {
     if (Interlocked.CompareExchange(ref done,1,0) == 0) 
     {
         Console.WriteLine("Done");
     }
  }
}

这里,值的更改和测试将作为一个单元执行:如果当前为0,则CompareExchange仅将值设置为1,并返回旧值.因此,只有一个线程会看到返回值为0.

另外要记住的一点是:你的问题很模糊,因为你还没有定义“线程安全”的含义.我已经猜到了你的意图,但你从来没有说清楚.阅读this blog post by Eric Lippert – 非常值得.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读