Csharp/C#教程:发布模式下的无限循环分享


发布模式下的无限循环

当我在调试模式下运行以下代码时,它将成功完成并退出。 但是,如果我在发布模式下运行以下代码,它将陷入无限循环而永远不会完成。

static void Main(string[] args) { bool stop = false; new Thread(() => { Thread.Sleep(1000); stop = true; Console.WriteLine("Set "stop" to true."); }).Start(); Console.WriteLine("Entering loop."); while (!stop) { } Console.WriteLine("Done."); } 

哪种优化导致它陷入无限循环?

我的猜测是主线程上的stop变量的处理器缓存。 在调试模式下,内存模型更严格,因为调试器需要能够在所有线程中提供变量状态的合理视图。

尝试创建一个字段并将其标记为volatile :

 volatile bool stop = false; static void Main(string[] args) { new Thread(() => { Thread.Sleep(1000); stop = true; Console.WriteLine("Set "stop" to true."); }).Start(); Console.WriteLine("Entering loop."); while (!stop) { } Console.WriteLine("Done."); } 

因为它不是线程安全的,所以更新子线程内的主线程变量stop 。 它永远是不可预测的。 要处理这种情况,请查看本文 。

volatile关键字指示编译器在每次从该字段读取时生成一个获取栅栏,并在每次写入该字段时生成一个释放栅栏。 获取栅栏可防止其他读/写在栅栏之前移动; 释放栅栏可防止在栅栏后移动其他读/写。 这些“半栅栏”比完全栅栏更快,因为它们为运行时和硬件提供了更多优化空间。

线程不安全代码是不可预测的。 主要问题是从另一个线程更改一个线程变量。 使变量全局或不稳定。 您可以通过以下方式完成

 static volatile bool stop = false; static void Main(string[] args) { new Thread(() => { Thread.Sleep(1000); stop = true; Console.WriteLine("Set "stop" to true."); }).Start(); Console.WriteLine("Entering loop."); while (!stop) { } Console.WriteLine("Done."); } 

看起来像局部变量值的某种优化 – 更改为字段使其终止正常(请注意,在实际代码中应使用volatile或正确的锁定):

上述就是C#学习教程:发布模式下的无限循环分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

 using System; using System.Threading; class Program { static bool stop = false; static void Main(string[] args) { new Thread(() => { Thread.Sleep(1000); stop = true; Console.WriteLine("Set "stop" to true."); }).Start(); Console.WriteLine("Entering loop."); while (!stop) { } Console.WriteLine("Done."); } } 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/1011915.html

(0)
上一篇 2021年12月29日
下一篇 2021年12月29日

精彩推荐