在C#中Release与Debug的区别小案例

我们都听说过C#写的代码 Release通常会比Debug性能要好一点跑得快一些。

先普及一些相关基础知识:

1)在CLR中将对sbyte、byteshortushortintuintcharfloatbool。以及引用类型保证读写时原子性的(long、double不是原子性读写)
变量中的所有字节都是一次性写入或读取的。 (
2)Framework Class Library(FCL) 保证所有静态方法都是线程安全的。这意味着假如两个线程同时调用一个静态方法,不会有数据被损坏。为什么? public static string Print(String str) { string val = ""; val += str; return val; } 因为静态方法内声明的变量,每个线程调用时都会新创建一份,而不会共用一个存储单元。比如这里的val每个线程都会创建自己的一份,因此不会有线程安全问题。
注意:静态变量,由于是在类加载时占用一个存储区每个线程都是共用这个存储区的,所以如果在静态方法里使用了静态变量;这就会有线程安全问题。 (
3)内存、CPU缓存(注:下列为简述内容,实际上不仅如此) CPU缓存,CPU集成的缓存。 内存,内存条硬件提供的存储空间。

下面看一个例子:

public class Program
{
       public static int bookNum = 0;

       public static void Main(string[] args)
      {
           Console.WriteLine("juster书的数量:" + bookNum);

           Thread juster = new Thread(() =>
          {
               Console.WriteLine("juster没带书,等待家长送书到学校...");

               while (bookNum == 0) {}

               Console.WriteLine("juster拿到书,开始上课听讲。");
          });
           juster.Name = nameof(juster);
           juster.Start();

           Thread parent = new Thread(() =>
          {
               Console.WriteLine("parent在屋里找书中...");

               Thread.Sleep(2000);

               Console.WriteLine("parent找到了书之后,送往学校...");

               SendBook();
          });
           parent.Name = nameof(parent);
           parent.Start();
      }

       public static void SendBook()
      {
           bookNum = 1;
      }
}

Run起来 对比一下Release 和Debug的结果。

有意思的是不是出来了

核心就是Release会优化 把  while (bookNum == 0)  直接给优化成了 while (0== 0) 

解决的办法 就是将 

public static int bookNum = 0;
改成
public static volatile int bookNum = 0;

最后说下volatile

其他类型(包括 double 和 long)无法标记为 volatile,因为对这些类型的字段的读取和写入不能保证是原子的。若要保护对这些类型字段的多线程访问,请使用 Interlocked 类成员或使用 lock 语句保护访问权限。

1  volatile 关键字只能应用于 class 或 struct 的字段。不能将局部变量声明为 volatile

2    volatile并不能用来做线程同步,它的主要作用时为了让多个线程之间能看到被修改过后最新的值。(也就是说可以让线程之间有权力访问 逻辑上不保证对不对)

3    C#不支持以传递引用的方式将volatile字段传给方法。

 int.TryParse("123", out x);

4 除了禁止编译优化,还有同步到内存中因为CPU每个核心都有自己Cache所以需要同步到内存中方便其他核心使用。

 

 

更详细的可以参考这篇文章 https://www.cnblogs.com/justzhuzhu/p/15550450.html
https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/volatile?WT.mc_id=WDIT-MVP-5004326



posted @ 2023-02-20 11:41  stweily  阅读(654)  评论(0编辑  收藏  举报