相关疑难解决方法(0)

联锁和不稳定

我有一个变量,我用来表示状态.它可以从多个线程读取和写入.

我正在使用Interlocked.ExchangeInterlocked.CompareExchange改变它.但是我从多个线程中读取它.

我知道volatile可以用来确保变量不在本地缓存,但总是直接从内存中读取.

但是,如果我将变量设置为volatile,则会生成有关使用volatile并使用ref传递给Interlocked方法的警告.

我想确保每个线程都读取变量的最新值而不是某些缓存版本,但我不能使用volatile.

有一个Interlocked.Read 但是它适用于64位类型,并且在紧凑的框架上不可用.它的文档说32位类型不需要它,因为它们已经在一次操作中执行.

如果您使用Interlocked方法进行所有访问,则互联网上有一些声明您不需要使用volatile.但是,您无法使用Interlocked方法读取32位变量,因此您无法使用Interlocked方法进行所有访问.

有没有办法在不使用锁的情况下完成我的变量的线程安全读写?

.net c# mono

70
推荐指数
2
解决办法
1万
查看次数

为什么不在System.Double和System.Long上使用volatile?

有人问过像我这样的问题,但我的情况有点不同.现在的问题是,"为什么volatile关键字不允许C#在类型System.DoubleSystem.Int64等?"

乍一看,我回答了我的同事,"好吧,在32位机器上,这些类型至少需要两个滴答才能进入处理器,.Net框架的目的是抽象出像这样的处理器特定细节. " 他回答说:"如果由于处理器特定的问题导致你无法使用某个功能,那么它就不会抽象出任何东西!"

他暗示一个特定于处理器的细节不应该出现在使用框架的人身上,这个框架"抽象"远离程序员的细节.因此,框架(或C#)应该抽象出那些并做它需要做的事情来提供相同的保证System.Double等等(无论是信号量,内存障碍还是其他).我认为框架不应该增加信号量的开销volatile,因为程序员不期望使用这样的关键字这样的开销,因为32位类型不需要信号量.64位类型的更大开销可能会让人感到意外,因此,更好的.Net框架只是不允许它,并且如果开销是可接受的,那么就可以在更大的类型上使用自己的信号量.

这导致我们调查volatile关键字的全部内容.(见页).该页面在说明中说明:

在C#中,在字段上使用volatile修饰符可确保对该字段的所有访问都使用VolatileRead或VolatileWrite.

嗯..... VolatileRead并且VolatileWrite都支持我们的64位类型!! 那么我的问题是,

"为什么volatile关键字不允许C#在类型System.DoubleSystem.Int64等?"

.net c# multithreading volatile

40
推荐指数
3
解决办法
7986
查看次数

读取由Interlocked在其他线程上更新的int

(这是重复:如何正确读取Interlocked.Increment'ed int字段?但是,在阅读了答案和评论之后,我仍然不确定正确的答案.)

有些代码我不拥有,也无法更改为使用在几个不同线程中增加int计数器(numberOfUpdates)的锁.所有通话都使用:

Interlocked.Increment(ref numberOfUpdates);
Run Code Online (Sandbox Code Playgroud)

我想在我的代码中读取numberOfUpdates.既然这是一个int,我知道它不会撕裂.但是,确保我获得最新价值的最佳方法是什么?看起来我的选择是:

int localNumberOfUpdates = Interlocked.CompareExchange(ref numberOfUpdates, 0, 0);
Run Code Online (Sandbox Code Playgroud)

要么

int localNumberOfUpdates = Thread.VolatileRead(numberOfUpdates);
Run Code Online (Sandbox Code Playgroud)

两者都有效(无论优化,重新排序,缓存等,都可以提供最新的价值)?一个比另一个更受欢迎吗?还有第三种选择更好吗?

.net c# multithreading interlocked interlocked-increment

35
推荐指数
3
解决办法
1万
查看次数

Interlocked.Exchange和Volatile.Write之间的区别?

Interlocked.Exchange和Volatile.Write有什么区别?

两种方法都更新某些变量的值.有人可以总结何时使用它们?

http://msdn.microsoft.com/ru-ru/library/bb337971http://msdn.microsoft.com/en-us/library/gg712713.aspx

特别是我需要更新我的数组的双项,我希望另一个线程看到最新的值.什么是首选?Interlocked.Exchange(ref arr[3], myValue)Volatile.Write(ref arr[3], info);在那里arr被声明为double

================================================== ==========================真实的例子,我声明了这样的双数组:

private double[] _cachedProduct;
Run Code Online (Sandbox Code Playgroud)

在一个线程中,我更新它:

        _cachedProduct[instrumentId] = calcValue;
        ...
        are.Set();
Run Code Online (Sandbox Code Playgroud)

在另一个线程中,我像这样读取这个数组:

        while(true) {
            are.WaitOne();
            ...
                result += _cachedProduct[instrumentId];
            ...
        }
Run Code Online (Sandbox Code Playgroud)

对我来说它只是工作正常.然而,为了确保"它将永远有效",无论它看起来我应该添加Volatile.WriteInterlocked.Exchange.因为双重更新不能保证是原子的http://msdn.microsoft.com/en-us/library/aa691278%28VS.71%29.aspx

在这个问题的答案中,我希望看到Volatile和Interlocked类的详细比较.为什么我们需要2节课?哪一个和何时使用?

c# .net-4.5

21
推荐指数
2
解决办法
3387
查看次数

Interlocked是否提供所有线程的可见性?

假设我有一个变量"counter",并且有几个线程通过使用Interlocked访问和设置"counter"的值,即:

int value = Interlocked.Increment(ref counter);
Run Code Online (Sandbox Code Playgroud)

int value = Interlocked.Decrement(ref counter);
Run Code Online (Sandbox Code Playgroud)

我可以假设,Interlocked所做的更改将在所有线程中可见吗?

如果没有,我该怎么做才能使所有线程同步变量?

编辑:有人建议我使用volatile.但是当我将"计数器"设置为volatile时,会出现编译器警告"对volatile字段的引用不会被视为volatile".

当我阅读在线帮助时,它说:"通常不应使用ref或out参数传递易失性字段".

c# multithreading visibility interlocked

7
推荐指数
2
解决办法
1701
查看次数

Threading.Volatile.Read(Int64)和Threading.Interlocked.Read(Int64)之间的区别?

Read(Int64).NET系统类System.Threading.Volatile和的方法有什么区别System.Threading.Interlocked

具体而言,关于(a)原子性和(b)内存排序,它们各自的保证/行为是什么。

请注意,这是关于Volatile阶级,不是volatile(小写)的关键字。


MS docs状态:

易读方法

读取字段的值。在需要它的系统上,插入一个内存屏障,以防止处理器按以下方式重新排序内存操作:如果在代码中此方法之后出现读取或写入,则处理器无法在此方法之前移动它。

...

退货 Int64

读取的值。不管处理器数量或处理器缓存状态如何,此值都是计算机中任何处理器最新写入的值。

Interlocked.Read(Int64)方法

返回作为原子操作加载的64位值。

似乎特别令人困惑的是,这些Volatile文档没有谈论原子性,并且这些Interlocked文档没有谈论排序/内存障碍。

旁注:作为参考:我更熟悉C ++原子API,其中原子操作也总是指定内存排序语义。


Pavel有用地提供的问题链接(和可传递链接)很好地解释了挥发性记忆屏障和原子无撕裂阅读的区别/正交性,但它们并没有解释这两个概念如何应用于这两个类别。

  • 是否Volatile.Read保证原子性?
  • 是否Interlocked.Read(或者,真的,任何的Interlocked功能)做出的内存为了任何保证?

c# multithreading volatile interlocked

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