在不锁定的情况下在不同线程中读取(仅)相同的非原子变量是否安全?

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

我有一个 class 方法,我想在其中在不同线程中同时读取相同的非原子 class 成员。该方法是 const,因此它不会写入正在读取的成员。在这种情况下不担心任何锁是否安全?

编辑: 我应该举个例子:

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*/});
//...
}

是安全的,前提是你能保证被读取的数据在多线程非同步访问期间不会改变。

(请注意,这段时间不仅包括线程 正在 调用您的 const 方法的短暂时刻,还包括线程 可以调用你的常量方法。因此,例如在许多程序中,这个不允许修改的时期可能从第一个子线程生成的那一刻开始,到最后一个子线程的那一刻结束已退出并 join()'d)

鉴于:

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

盲目读取可能已被其他线程修改的非原子值是不是本质上安全的,即使您知道 100% 肯定不会发生任何修改与读取同时进行。

两个线程之间必须同步才能从读取线程看到修改。

潜在的问题不仅仅是读取过时的值。如果编译器可以确定在同一内存位置的两次后续读取之间没有发生同步,则完全允许只读取一次并缓存结果。

有多种方法可以完成同步,在给定场景中哪种方法最好取决于上下文。

有关详细信息,请参阅 https://en.cppreference.com/w/cpp/language/memory_model

但是,一旦建立同步,任何数量的线程都可以同时从同一内存位置读取。

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?

是的,它是 100% 安全的。我假设唯一的问题是多个线程正在读取,并且如果单个线程正在读取,代码将是安全的。读取相同数据的其他线程对读取是否安全没有影响。

数据竞争只能发生在读取和修改之间。因此,如果来自一个线程的一次读取不会与任何修改竞争,那么其他读取也不会。