简体   繁体   中英

Is it safe to read(only) the same non-atomic variable in different threads without locking?

I have a class method in which I want to read the same non-atomic class member simultaneously in different threads. The method is const , so it doesn't write to the member being read. Is it safe to not bother about any locks in this case?

Edit: I should have given an example:

class SomeClass()
{
    public:
        void someMethod() const;
//...
    private:
        std::string someMemeber_; // might be changed by some methods
//...
}

void SomeClass::someMethod() const
{
    std::jthread thr1([](){/*read someMember_ here*/});
    std::jthread thr2([](){/*read someMember_ here*/});
//...
}

It is safe, provided you can guarantee that the data being read won't change during the period that multiple threads have unsynchronized access to it.

(Note that this period includes not just the brief moments in time when threads are calling your const-method, but the entire region of time when a thread could call your const-method. So for example in many programs this no-modifications-allowed period might begin at the moment when the first child-thread is spawned, and end at the moment the last child-thread has exited and been join() 'd)

Given that:

Yes, the value can be changed by other methods, but not during the execution of the method with multiple threads.

It is not inherently safe to blindly read non-atomic values that have potentially been modified by some other thread even if you know for 100% certain that no modification will be happening concurrently with the reads.

There has to be syncrhonization between the two threads before a modification is seen from reading threads.

The potential problems go beyond reading an out-of-date value. If the compiler can establish that there is no synchronization happening between two subsequent reads of the same memory location, it's perfectly allowed to only read it once and cache the result.

There are various ways for the synchronization to be done, and which one is best in a given scenario will depend on the context.

see https://en.cppreference.com/w/cpp/language/memory_model for more details

However, once synchronization has been established, any number of threads can concurrently read from the same memory location.

I have a class method in which I want to read the same non-atomic class member simultaneously in different threads. The method is const, so it doesn't write to the member being read. Is it safe to not bother about any locks in this case?

Yes, it is 100% safe. I am assuming that the only issue is that multiple threads are reading and that the code would be safe if a single thread were reading. That additional threads are reading the same data has no effect on whether the reads are safe or not.

A data race can only occur between a read and a modification. So if one read from one thread wouldn't race with any modifications, additional reads can't either.

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