繁体   English   中英

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

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

我有一个类方法,我想在不同的线程中同时读取同一个非原子类成员。 该方法是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*/});
//...
}

它是安全的,前提是您可以保证在多个线程对其进行非同步访问期间读取的数据不会更改。

(请注意,这期间不仅包括在当线程调用您的常量法时的短暂瞬间,但时间的整个区域,当一个线程可以打电话给你的常数法。因此,例如在许多程序中,这没有修改,允许期间可能从第一个子线程产生的那一刻开始,并在最后一个子线程退出并被join() 'd) 的那一刻结束

鉴于:

是的,该值可以通过其他方法更改,但不能在具有多个线程的方法执行期间更改。

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

在从读取线程看到修改之前,两个线程之间必须同步

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

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

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

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

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

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

数据竞争只能发生在读取和修改之间。 因此,如果从一个线程中读取的内容不会与任何修改竞争,那么额外的读取也不能。

暂无
暂无

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

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