如果我在多个线程中访问单个整数类型(例如 long、int、bool 等),我是否需要使用同步机制(例如互斥体)来锁定它们。我的理解是,作为原子类型,我不需要锁定对单个线程的访问,但我看到很多代码确实使用了锁定。对此类代码进行分析表明,使用锁会对性能产生重大影响,因此我宁愿不这样做。因此,如果我正在访问的项目对应于总线宽度整数(例如 32 位处理器上的 4 个字节),当跨多个线程使用它时,我是否需要锁定对其的访问?换句话说,如果线程 A 正在写入整数变量 X,而线程 B 正在读取同一变量,则线程 B 是否有可能最终将前一个值的几个字节与前一个值的几个字节混合在一起。正在写入的值?这个架构是否依赖,例如在 32 位系统上 4 字节整数可以,但在 64 位系统上 8 字节整数不安全?
Edit:刚看到这个相关帖子这有一定帮助。
你永远不会锁定一个值——你只是锁定一个值上的操作。
C 和 C++ 没有明确提及线程或原子操作 - 因此看起来可以或应该是原子的操作 - 语言规范不保证是原子的。
无可否认,这是一个非常不正常的编译器,它管理对 int 的非原子读取:如果您有一个读取值的操作 - 可能不需要保护它。然而,如果它跨越机器字边界,它可能是非原子的。
操作简单如m_counter++
涉及获取、增量和存储操作 - 竞争条件:另一个线程可以在获取之后但存储之前更改值 - 因此需要通过互斥体进行保护 - 或者找到您的编译器对互锁操作的支持。 MSVC 具有像 _InterlockedIncrement() 这样的函数,只要所有其他写入都类似地使用互锁 api 来更新内存位置,它就会安全地增加内存位置 - 这比调用关键部分要轻量几个数量级。
GCC 具有诸如__sync_add_and_fetch
它还可用于对机器字值执行互锁操作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)