繁体   English   中英

i ++线程安全

[英]i++ thread safe

这是该问题的补充,我可以得出结论,在c / c ++中,此类操作不是线程安全的。

我的问题是, 无论如何在线程安全性方面我们都需要获得 请注意,这里的锁是一个逻辑概念,即使您使用InterlockedIncrement()或c ++ 0x原子类型,也可以使用cmpxchg从概念上获取锁。

例如,如果只有一个写入线程和多个读取线程,那么读取线程会得到奇怪的值吗? 我假设

  1. 类型i在x86平台上为32位,在x64平台上为64位。
  2. 旧值或新值都可以。

对于单个写入器和多个读取器,使用该值是线程安全的 ,但在一般情况下,此类操作不是线程安全的(因此需要锁定或使用原子操作)。 另外, 线程安全的含义在这里非常有限。

如果仅在一个线程中执行i++ ,则其他线程将看到旧值或新值。 您提到在这两个平台上,这些值是原子存储/加载的,因此它们不能获得一半的值。 但是,通常情况并非如此,例如x86上的64位值不是原子的,因此读取器可以获得旧值的一半和新值的一半。 因此,这里的线程安全性是特定于平台的。

但是,您仍然必须小心。 如果这是简单的int则优化器可能会简单地放弃装入操作(也许将副本保留在寄存器中)。 在这种情况下,读者将永远不会获得新的价值。 如果您要循环执行此操作,则至关重要。 不幸的是,唯一正确的标准方法是使用atomic<T>类型的C ++ 0x(现在, 易失性服务用于某些编译器)。

如果确实添加第二个编写器,则增量运算符当然根本不是线程安全的。 但是,您可以在此处使用原子添加函数,使其再次线程安全。

如果您有权访问Qt,请查看其QAtomicInt类。 它是完全独立的,有可能(我设法做到)从那里拉走所有必要的东西,以拥有一个独立的可移植atomic_int类。

它提供原子fetch_and_storefetch_and_addcompare_and_swap ,具有屏障语义(获取,释放,完整,无屏障)的incrementdecrement ,尽管在x86上,每个操作都是完全屏障。

也有一个QAtomicPointer类模板。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM