相关疑难解决方法(0)

如何正确读取Interlocked.Increment'ed int字段?

假设我有一个非易失性的int字段,以及一个它Interlocked.Increment的线程.另一个线程可以直接安全地读取它,还是读取也需要互锁?

我以前认为我必须使用互锁读取来保证我看到当前值,因为毕竟,该字段不是易失性的.我一直在Interlocked.CompareExchange(int, 0, 0)努力实现这一目标.

但是,我偶然发现了这个答案,这表明实际的普通读取总会看到Interlocked.Incremented值的当前版本,并且因为int读取已经是原子的,所以不需要做任何特殊的事情.我还发现了Microsoft拒绝Interlocked.Read(ref int)请求的请求,进一步表明这完全是多余的.

那么我能真正安全地阅读这样一个int领域的最新价值Interlocked吗?

.net c# multithreading thread-safety

56
推荐指数
4
解决办法
1万
查看次数

C#中的易失性字段

从规范10.5.3挥发性字段:


volatile字段的类型必须是以下之一:

  • 引用类型.

  • 类型byte,sbyte,short,ushort,int,uint,char,float,bool,System.IntPtr或System.UIntPtr.

  • 具有枚举基类型byte,sbyte,short,ushort,int或uint的枚举类型.


首先,我想确认我的理解是正确的:我猜上面的类型可以是volatile,因为它们在内存中存储为4字节单元(因为它的地址对于引用类型),这保证了读/写操作是原子的.double/long/etc类型不能是volatile,因为它们不是原子读/写,因为它们在内存中超过4个字节.我的理解是否正确?

第二,如果第一个猜测是正确的,为什么用户定义的结构只有一个int字段(或类似的东西,4个字节就可以)不能是易失性的?理论上它是原子的吗?或者仅仅是因为所有用户定义的结构(可能超过4个字节)不允许设计的易失性?

.net c# clr language-features volatile

11
推荐指数
1
解决办法
3422
查看次数

C#volatile双

因为只有引用类型和一些原语(包括float,但不是double,我不确定原因,我很高兴听到原因)可以声明为volatile,如果我在类中包装double然后声明它作为volatile(如下所示),double属性是'read write'线程安全,就像任何其他volatile一样,还是我还应该看看锁定?

public class MyThreadedClass
{
    volatile VolatileDouble voldub;
}

public class VolatileDouble
{
    public double Double { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

.net c# volatile

10
推荐指数
2
解决办法
4964
查看次数

为什么Datetime对象不能在c#中出现波动?

我可以想到一些使用案例,让DateTime对象成为原子非常有用.从语言设计的角度来看,有什么优势可以使DateTime不稳定?

c# datetime volatile

1
推荐指数
1
解决办法
176
查看次数