gpt4 book ai didi

c# - 为什么这个程序在没有 bool 条件变量的波动性的情况下不会进入无限循环?

转载 作者:太空狗 更新时间:2023-10-30 00:16:10 24 4
gpt4 key购买 nike

我想知道什么时候我需要将一个变量声明为 volatile。为此,我编写了一个小程序,并期望它会因为缺少条件变量的波动性而进入无限循环。它没有进入无限循环并且在没有 volatile 关键字的情况下工作正常。

两个问题:

  1. 我应该在下面的代码 list 中更改什么 - 以便它绝对需要使用 volatile?

  2. C# 编译器是否足够聪明,可以将变量视为易变的 - 如果它发现一个变量正在从不同的线程访问?

上面的内容引发了我更多的问题:)

一个。 volatile 只是一个提示吗?

我什么时候应该在多线程上下文中将变量声明为 volatile?

对于线程安全类,所有成员变量都应该声明为 volatile 吗?是不是太过分了?

代码 list (重点是易变性而不是线程安全):

class Program
{
static void Main(string[] args)
{
VolatileDemo demo = new VolatileDemo();
demo.Start();

Console.WriteLine("Completed");
Console.Read();
}
}

public class VolatileDemo
{
public VolatileDemo()
{
}

public void Start()
{
var thread = new Thread(() =>
{
Thread.Sleep(5000);
stop = true;
});

thread.Start();

while (stop == false)
Console.WriteLine("Waiting For Stop Event");
}

private bool stop = false;
}

谢谢。

最佳答案

首先,Joe Duffy says "volatile is evil" - 这对我来说已经足够了。

如果您确实想考虑 volatile,则必须从内存栅栏和优化的角度考虑 - 通过编译器、抖动和 CPU。

在 x86 上,写入是释放栅栏,这意味着您的后台线程会将 true 值刷新到内存中。

因此,您正在寻找的是在循环谓词中缓存 false 值。编译器或抖动可能优化谓词并且只对其求值一次,但我猜它不会为读取类字段而这样做。 CPU 不会缓存 false 值,因为您正在调用包含栅栏的 Console.WriteLine

此代码需要 volatile 并且在没有 Volatile.Read 的情况下永远不会终止:

static void Run()
{
bool stop = false;

Task.Factory.StartNew( () => { Thread.Sleep( 1000 ); stop = true; } );

while ( !stop ) ;
}

关于c# - 为什么这个程序在没有 bool 条件变量的波动性的情况下不会进入无限循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8709918/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com