C# 中的原始数据类型是原子的(线程安全的)吗?

发布于 2024-08-24 21:41:07 字数 41 浏览 6 评论 0 原文

例如,多线程时是否需要锁定 bool 值?

For example, do I need to lock a bool value when multithreading?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蓝礼 2024-08-31 21:41:07

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

读取和写入适合单个字的数据类型(32 位处理器上的 int,64 位处理器上的 long)在技术上是“原子的”,但是抖动和/或处理器可以决定重新排序指令,从而创建意外的竞争条件,因此您需要使用 lock 序列化访问,使用 Interlocked 类进行写入(并且在某些情况下读取),或声明变量易失性

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

There is no such thing as an atomic type. Only operations can be atomic.

Reading and writing a data type that fits into a single word (int on a 32-bit processor, long on a 64-bit processor) is technically "atomic", but the jitter and/or processor can decide to reorder instructions and thus create unexpected race conditions, so you either need to serialize access with lock, use the Interlocked class for writes (and in some cases reads), or declare the variable volatile.

The short answer is: If two different threads may access the same field/variable and at least one of them will be writing, you need to use some sort of locking. For primitive types that's generally the Interlocked class.

一紙繁鸢 2024-08-31 21:41:07

有点像。关于这个有一个很好的线程 此处,但简短的版本是,虽然给定的读取或写入可能是原子的,但这几乎从来不是您正在做的事情。例如,如果要递增一个整数,则需要 1) 读取该值,2) 为该值加一,3) 存储回该值。这些操作中的任何一个都可以被中断。

这就是“互锁”等课程的原因。

Sort of. There's an excellent thread about this here, but the short version is, while a given read or write may be atomic, that's almost never what you're doing. For example, if you want to increment an integer, you need to 1) read the value, 2) add one to the value and 3) store the value back. Any of those operations can be interrupted.

That's the reason for classes such as "Interlocked".

谁对谁错谁最难过 2024-08-31 21:41:07

类似的问题此处

要获得明确的答案,请访问
规格:)

CLI 的第 I 部分,第 12.6.6 节
规范规定:“符合要求的 CLI 应
保证读写访问
正确对齐内存位置
不大于本机字大小
当所有写访问都为原子时
一个位置的大小相同。”

这证实了 s_Initialized
永远不会不稳定,并且读取
并写入原始类型是
原子。

互锁会产生内存屏障
以防止处理器
重新排序读取和写入。锁
创建唯一需要的障碍
这个例子。

约翰。

本质上,您不会因不锁定布尔值而遇到“崩溃”问题。您可能遇到的是更新或读取布尔值的顺序的竞争条件。如果您想保证布尔值按特定顺序写入/读取,那么您需要使用某种锁定机制。

Similar Question here

For the definitive answer go to the
spec. :)

Partition I, Section 12.6.6 of the CLI
spec states: "A conforming CLI shall
guarantee that read and write access
to properly aligned memory locations
no larger than the native word size is
atomic when all the write accesses to
a location are the same size."

So that confirms that s_Initialized
will never be unstable, and that read
and writes to primitve types are
atomic.

Interlocking creates a memory barrier
to prevent the processor from
reordering reads and writes. The lock
creates the only required barrier in
this example.

John.

Essentially, you wont have a "crash" problem from not locking a bool. What you may have is a race condition for the order of which the bool is updated or read. If you want to garuntee that the bool is written to/read from in a specific order, then you'd want to use some sort of locking mechanism.

好听的两个字的网名 2024-08-31 21:41:07

静态基元类型是线程安全的,因此您不需要锁定这些类型变量。但是,不保证任何原始类型的实例变量都是如此。请参阅此处: 像 bool 这样的基本类型是线程安全的吗?

MSDN PrimitiveType Class

这是另一个有用的链接,我可能也会感兴趣,我发现该解决方案非常引人注目:所以问题:我如何知道 C# 方法是否是线程安全的?

Static primitive types are threadsafe, so you don't need to lock those typed variables. However, any instance variable of a primitive type is not guaranteed to be. See here: Are primitive types like bool threadsafe ?

MSDN PrimitiveType Class

And here's another useful link that might also be of interest which I find the solution very compelling: SO Question: How do I know if a C# method is thread safe?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文