我在MS文档中读到,在32位Intel计算机上分配64位值不是原子操作; 也就是说,操作不是线程安全的.这意味着如果两个人同时为静态分配值Int64
字段则无法预测该字段的最终值.
三部分问题:
这是真的吗?
这是我在现实世界中会担心的吗?
如果我的应用程序是多线程的,我真的需要Int64
用锁定代码包围我的所有作业吗?
Mehrdad Afsh.. 18
这不是您遇到的每个变量.如果某个变量用作共享状态或某些东西(包括但不限于某些 static
字段),则应该处理此问题.由于在闭包或迭代器转换中被关闭而未被提升的局部变量完全没有问题,并且一次由单个函数(因此,单个线程)使用.
这不是您遇到的每个变量.如果某个变量用作共享状态或某些东西(包括但不限于某些 static
字段),则应该处理此问题.由于在闭包或迭代器转换中被关闭而未被提升的局部变量完全没有问题,并且一次由单个函数(因此,单个线程)使用.
即使写入是原子的,也可能在访问变量时仍需要锁定.如果你不这样做,你至少必须创建变量volatile
以确保所有线程在下次读取变量时看到新值(这几乎总是你想要的).这可以让你做原子的,易变的集合 - 但是只要你想做更有趣的事情,比如给它添加5,你就会回到锁定状态.
无锁编程是非常非常难以正确的.您需要确切地知道自己在做什么,并将复杂性保持在尽可能小的代码段.就个人而言,除了众所周知的模式之外,我甚至很少尝试尝试它,例如使用静态初始化程序初始化集合,然后从集合中读取而不锁定.
Interlocked
在某些情况下使用该类可能会有所帮助,但是锁定它几乎总是容易得多.无可争议的锁是"非常便宜的"(不可否认,它们随着更多内核而变得昂贵,但所有内容也是如此) - 在你有充分证据证明它实际上会产生重大影响之前,不要乱用无锁代码.
MSDN:
分配此类型的实例在所有硬件平台上都不是线程安全的,因为该实例的二进制表示可能太大而无法在单个原子操作中分配.
但是也:
与任何其他类型一样,必须通过锁保护对包含此类实例的共享变量的读写,以保证线程安全.