简体   繁体   English

i ++线程安全

[英]i++ thread safe

It is the addition to this question , I can conclude that in c/c++, such operation isn't thread-safe. 这是该问题的补充,我可以得出结论,在c / c ++中,此类操作不是线程安全的。

my question is need we acquire lock in any case in terms of thread-safety? 我的问题是, 无论如何在线程安全性方面我们都需要获得 note here lock is a logical concept, even if you use InterlockedIncrement() or c++0x atomic type, lock is acquired conceptually by using cmpxchg . 请注意,这里的锁是一个逻辑概念,即使您使用InterlockedIncrement()或c ++ 0x原子类型,也可以使用cmpxchg从概念上获取锁。

For example, if there are only one-write-thread and many-read-threads, can read-thread get strange value? 例如,如果只有一个写入线程和多个读取线程,那么读取线程会得到奇怪的值吗? I assume 我假设

  1. The type i is 32-bit on x86 platform or 64-bit on x64 platform. 类型i在x86平台上为32位,在x64平台上为64位。
  2. Either old value or new value is OK. 旧值或新值都可以。

In the case of a single writer and many-readers to this single value it is thread-safe , but in the general case such operations are not thread-safe (thus needing a lock or using atomic operations). 对于单个写入器和多个读取器,使用该值是线程安全的 ,但在一般情况下,此类操作不是线程安全的(因此需要锁定或使用原子操作)。 Also, what thread-safe means is very limited here. 另外, 线程安全的含义在这里非常有限。

If you simply do i++ in one thread, the other threads will either see the old value or the new value. 如果仅在一个线程中执行i++ ,则其他线程将看到旧值或新值。 On the two platforms you mention the values are atomically stored/loaded, so they cannot get half a value. 您提到在这两个平台上,这些值是原子存储/加载的,因此它们不能获得一半的值。 This is however not true in general, for example a 64-bit value on x86 will not be atomic, so the reader could get half of the old value and half of the new value. 但是,通常情况并非如此,例如x86上的64位值不是原子的,因此读取器可以获得旧值的一半和新值的一半。 So thread-safety here is very platform specific. 因此,这里的线程安全性是特定于平台的。

You still have to be careful however. 但是,您仍然必须小心。 If this is a plain int the optimizer may simply discard the load operation (perhaps keep a copy in a register). 如果这是简单的int则优化器可能会简单地放弃装入操作(也许将副本保留在寄存器中)。 In this case the reader will never get a new value. 在这种情况下,读者将永远不会获得新的价值。 This is vital if you are doing this in a loop. 如果您要循环执行此操作,则至关重要。 Unfortunately the only standards correct way of doing this is with C++0x using an atomic<T> type ( volatile kind of serves this purpose now for some compilers). 不幸的是,唯一正确的标准方法是使用atomic<T>类型的C ++ 0x(现在, 易失性服务用于某些编译器)。

If you do add a second writer the increment operator is of course not thread-safe at all. 如果确实添加第二个编写器,则增量运算符当然根本不是线程安全的。 You could however here use an atomic add function which would make it thread safe again. 但是,您可以在此处使用原子添加函数,使其再次线程安全。

If you have access to Qt, check out their QAtomicInt class. 如果您有权访问Qt,请查看其QAtomicInt类。 It is quite self contained, it is possible (I managed to do it) to pull all the necessary stuff from there to have a standalone portable atomic_int class. 它是完全独立的,有可能(我设法做到)从那里拉走所有必要的东西,以拥有一个独立的可移植atomic_int类。

It provides atomic fetch_and_store , fetch_and_add , compare_and_swap , increment and decrement with barrier semantics (acquire, release, full, no barrier), although on x86 every operation will be full barrier. 它提供原子fetch_and_storefetch_and_addcompare_and_swap ,具有屏障语义(获取,释放,完整,无屏障)的incrementdecrement ,尽管在x86上,每个操作都是完全屏障。

There is a QAtomicPointer class template too. 也有一个QAtomicPointer类模板。

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

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