挥发性和互锁 [英] Volatile & Interlocked

查看:88
本文介绍了挥发性和互锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用volatile关键字,如果我打算使用任何

互锁API,会产生问题。如果我使用以下

行,编译器会生成错误,例如:

Interlocked.Increment(引用计数);

该错误表示不能将volatile字段用作ref或out,但如果我不使用volatile字段,则可以通过某种方法缓存该值

只是读取字段。


例如,考虑三个线程使用的整数字段。两个

线程打算增加字段的值,而第三个线程只需

希望检查该值。例如,考虑

字段的初始值为5.


如果两个写入程序线程都使用互锁API递增值,则

该字段的最终值保证为7.如果不使用

互锁API,最终值可能为6.因此,使用
$ b在这种情况下,$ b互锁API是必须的。


如果没有将字段标记为volatile,则读者线程可能总是看到

值为5。


可以看出,在某些情况下我们需要两种机制。


这种情况​​可能有什么解决方案?

Using the "volatile" keyword, creates a problem if I intend to use any of
the interlocked APIs. The compiler generates an error if I use the following
line, for example:

Interlocked.Increment(ref count);

The error says that a volatile field cannot be used as ref or out, but if I
don''t use the volatile field, the value may be cached away in some method
that is just reading the field.

Consider, for example, an integer field being used by three threads. Two
threads intend to increment the value of the field while the third one just
wishes to check the value. Consider, for example, the initial value of the
field is 5.

If both the writer threads increment the value using the interlocked API,
the final value of the field is guaranteed to be 7. Without the use of the
interlocked API, the final value could be 6. Therefore, using the
interlocked API is a must in this case.

Without the field being marked as volatile, the reader thread may always see
the value as 5.

As can be seen, we need both the mechanisms under some cases.

What might be the solution for such situations?

推荐答案

嗨...


您是否将该字段标记为易变?


我们很清楚,当你将变量变为volatile时,就意味着

有可能异步更改项目。在

一般情况下,如果您控制线程等,您只需使用锁定

关键字:


lock(obj){

//做工作

}


如果您需要进程间控制,请考虑使用Mutex。

如果您需要多个读者与一个作者,所有人都在同一个

变量上,请考虑.NET框架中提供的ReaderWriterLock类

类库。


希望这会有所帮助,

John Puopolo

如果你有读写器线程正在寻找有一个作家的多个读者

,你可以使用


" Pierre" < balioglu@DONOTSPAM_in.tum.de>在消息中写道

news:Ow **************** @ TK2MSFTNGP10.phx.gbl ...
Hi...

Are you marking the field as "volatile"?

Just so we are clear, when you make a variable as volatile, it means that
there is a chance that the item could be changed asynchronously. In
general, if you control the threads, etc., you can simply use the "lock"
keyword:

lock(obj) {
// do work
}

If you need inter-process control, consider using a Mutex.
If you need multple readers with one writer, all banging away on the same
variable, consider the ReaderWriterLock class provided in the .NET framework
class library.

Hope this helps,
John Puopolo
If you have reader/writer threads are are looking to have multiple readers
with one writer, you can use the

"Pierre" <balioglu@DONOTSPAM_in.tum.de> wrote in message
news:Ow****************@TK2MSFTNGP10.phx.gbl...
使用&挥发性"关键字,如果我打算使用任何互锁API,会产生问题。如果我使用
后续行,编译器会生成错误,例如:

Interlocked.Increment(引用计数);

错误表示易失性字段不能用作ref或out,但是如果
我不使用volatile字段,那么值可以用某种方法缓存掉
只是在阅读字段。
线程打算增加字段的值,而第三个线程
只是想检查值。例如,考虑
字段的初始值是5.

如果两个写入器线程都使用互锁API递增值,则该字段的最终值为保证是7.如果没有使用
互锁API,最终值可能是6.因此,在这种情况下,使用
互锁API是必须的。

该字段被标记为易失性,读者线程可能总是
将值视为5.

可以看出,在某些情况下我们需要两种机制。
Using the "volatile" keyword, creates a problem if I intend to use any of
the interlocked APIs. The compiler generates an error if I use the following line, for example:

Interlocked.Increment(ref count);

The error says that a volatile field cannot be used as ref or out, but if I don''t use the volatile field, the value may be cached away in some method
that is just reading the field.

Consider, for example, an integer field being used by three threads. Two
threads intend to increment the value of the field while the third one just wishes to check the value. Consider, for example, the initial value of the
field is 5.

If both the writer threads increment the value using the interlocked API,
the final value of the field is guaranteed to be 7. Without the use of the interlocked API, the final value could be 6. Therefore, using the
interlocked API is a must in this case.

Without the field being marked as volatile, the reader thread may always see the value as 5.

As can be seen, we need both the mechanisms under some cases.

What might be the solution for such situations?



皮埃尔,


锁关键字(Monitor.Enter和Monitor.Exit)具有不稳定的

读/写语义。您可以使用它而不是Interlocked

类。理解起来要容易得多,但执行起来要慢得多。在大多数情况下,执行速度较慢并不重要。


如果您仍然希望使用Interlocked类,您将被视为

删除volatile修饰符。我认为* Interlocked类

隐含地创建了一个内存屏障。有人可以证实吗?如果是这样,那么

您可以使用Interlocked.CompareExchange

方法安全地读取该值。


int safeRead = Interlocked.CompareExchange (引用计数,0,0);


涉及易失性读/写,内存屏障和内存的主题

模型非常令人困惑。犯错很容易。


Brian


Pierre写道:
Pierre,

The lock keyword (Monitor.Enter and Monitor.Exit) has volatile
read/write semantics. You could use that instead of the Interlocked
class. It would be significantly easier to understand, but would be
slower to execute. The slower execution will not matter in most cases.

If you still wish to use the Interlocked class you''ll be foreced to
remove the volatile modifier. I *think* the Interlocked class
implicitly creates a memory barrier. Can someone confirm? If so then
you can safely read the value using the Interlocked.CompareExchange
method.

int safeRead = Interlocked.CompareExchange(ref count, 0, 0);

Topics involving volatile read/writes, memory barriers, and the memory
model are very confusing. It''s easy to make a mistake.

Brian

Pierre wrote:
使用"挥发性"关键字,如果我打算使用任何互锁API,会产生问题。如果我使用以下行,编译器会生成错误,例如:

Interlocked.Increment(引用计数);

错误表示易失性字段不能用作ref或out,
但是如果我不使用volatile字段,那么值可能会被某些只是阅读该字段的方法缓存掉。
两个线程打算增加字段的值,而第三个线程只想检查值。例如,考虑该字段的初始值为5.

如果两个编写器线程都使用互锁的API递增值,则该字段的最终值为保证为7.如果没有使用互锁API,最终值可能是6.因此,在这种情况下,使用互锁API是必须的。

该字段被标记为易失性,读者线程可能总是将值视为5.

可以看出,在某些情况下我们需要两种机制。
Using the "volatile" keyword, creates a problem if I intend to use
any of the interlocked APIs. The compiler generates an error if I
use the following line, for example:

Interlocked.Increment(ref count);

The error says that a volatile field cannot be used as ref or out,
but if I don''t use the volatile field, the value may be cached away
in some method that is just reading the field.

Consider, for example, an integer field being used by three threads.
Two threads intend to increment the value of the field while the
third one just wishes to check the value. Consider, for example, the
initial value of the field is 5.

If both the writer threads increment the value using the interlocked
API, the final value of the field is guaranteed to be 7. Without the
use of the interlocked API, the final value could be 6. Therefore,
using the interlocked API is a must in this case.

Without the field being marked as volatile, the reader thread may
always see the value as 5.

As can be seen, we need both the mechanisms under some cases.

What might be the solution for such situations?








" Brian Gideon" <峰; br ********* @ yahoo.com>在消息中写道

news:11 ********************** @ o13g2000cwo.googlegr oups.com ...

"Brian Gideon" <br*********@yahoo.com> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...
Pierre,

lock关键字(Monitor.Enter和Monitor.Exit)具有易失性的读/写语义。您可以使用它而不是Interlocked
类。理解起来要容易得多,但执行速度会慢一些。在大多数情况下,执行速度较慢并不重要。

如果您仍然希望使用Interlocked类,您将被视为
删除volatile修饰符。我认为* Interlocked类
隐含地创建了一个内存屏障。有人可以证实吗?如果是这样,那么你可以使用Interlocked.CompareExchange
方法安全地读取值。

int safeRead = Interlocked.CompareExchange(ref count,0,0);

涉及易失性读/写,内存障碍和内存模型的主题非常令人困惑。犯错很容易。

Brian
Pierre,

The lock keyword (Monitor.Enter and Monitor.Exit) has volatile
read/write semantics. You could use that instead of the Interlocked
class. It would be significantly easier to understand, but would be
slower to execute. The slower execution will not matter in most cases.

If you still wish to use the Interlocked class you''ll be foreced to
remove the volatile modifier. I *think* the Interlocked class
implicitly creates a memory barrier. Can someone confirm? If so then
you can safely read the value using the Interlocked.CompareExchange
method.

int safeRead = Interlocked.CompareExchange(ref count, 0, 0);

Topics involving volatile read/writes, memory barriers, and the memory
model are very confusing. It''s easy to make a mistake.

Brian




你是对的,Interlocked函数用

aquire&释放语义,因此不需要volatile修饰符。


Willy。



You are right, the Interlocked functions do create memory barriers with
aquire & release semantics, so there is no need for the volatile modifier.

Willy.


这篇关于挥发性和互锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆