简体   繁体   中英

i++ thread safe

It is the addition to this question , I can conclude that in c/c++, such operation isn't thread-safe.

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 .

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.
  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. 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. 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). 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).

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. 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.

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.

There is a QAtomicPointer class template too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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