2010-03-12 55 views
8

例如,多线程时,我需要锁定一个bool的值吗?原子数据类型在C#原子(线程安全)?

+2

在大多数情况下,如果你从两个线程写入,你应该使用一个锁... – 2010-03-12 15:37:40

+0

然后,我会做什么米奇说。 =) – 2010-03-12 15:46:33

回答

15

有没有这样的东西类型。只有操作可以是原子的。

读写装配到一个字一个数据类型(int上的32位处理器,long上的64位处理器)在技术上是“原子”,但抖动和/或处理器可以决定重新排序指令,从而产生意想不到的竞争条件,因此您需要使用lock序列化访问,使用Interlocked类写入(以及在某些情况下读取),或声明变量volatile

简短的回答是:如果两个不同的线程可以访问相同的字段/变量,并且至少其中一个将写入,则需要使用某种锁定。对于通常是Interlocked类的原始类型。

+0

是的操作可以是原子操作,但是有些特定的数据类型被称为原子类型,因为它们允许原子操作,因为它们的内存大小要求与系统上的字大小有关。 – NebuSoft 2010-03-12 16:20:32

+1

@NebuSoft:是指由谁或什么?当然不是C#规范。请参见5.5节*变量引用的原子性*,它特别指代* reads的原子性*和*写* - 而不是类型本身。每种类型都可以允许特定的原子操作,并且它只需要两行代码就可以对原始类型执行非原子操作。 – Aaronaught 2010-03-12 17:41:14

+3

对不起,我指的是一般条款: http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/atomic/package-summary.html http:///www-2.cs.cmu.edu/afs/cs/project/pscico/doc/nesl/manual/node14.html http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp ?topic =/com.ibm.ddi.doc/ddi160.htm http://download.oracle.com/docs/cd/B28359_01/gateways.111/b31053/ims_datatype_conver.htm 我只是指出通常将变量称为基于一般意义上的类型的原子。 – NebuSoft 2010-03-12 22:07:59

2

类似的问题here

对于明确的答案转到 规范。 :)

分区我的CLI 规范规定的第12.6.6:“A符合CLI须 保证读写访问 正确对齐的内存位置 不超过本地字大小是 原子时所有对 位置的写入访问都是相同的大小。“

因此,确认s_Initialized 永远是不稳定的,而且阅读 和写入primitve类型 原子。

联锁创建内存屏障 以防止处理器从 重新排序读取和写入。锁 创建 此示例中唯一所需的屏障。

John。

基本上,你不会有一个“崩溃”的问题,因为没有锁定布尔。你可能拥有的是bool更新或阅读顺序的竞争条件。如果你想要知道bool是以特定的顺序写入/读取的,那么你会想要使用某种锁定机制。

2

排序的。关于这个here有一个很好的线索,但简短的版本是,而给定的读或写可能是原子的,这几乎从来没有你在做什么。例如,如果你想增加一个整数,你需要1)读取数值,2)给数值加1,3)存回数值。任何这些操作都可能被中断。

这就是诸如“互锁”之类的原因。