我有一个类MyClass,它的函数A多次并行执行。然后,函数B只应该执行一次。我的初始设置看起来很简单,但我怀疑它是否是线程安全的。我怎么才能保证线程安全?我在用C++11。
class MyClass {
    public:
        void A() {
            static bool execute_B = true;
            if (execute_B) {
                execute_B = false;
                B();
            }
        }
    private:
        void B() {
            std::cout << "only execute this once\n";
        }
};发布于 2016-07-12 09:38:20
是的,您的代码是不安全的:在if语句的正文中有几个线程可以进入,然后execute_B才会被设置为false。而且,execute_B不是原子的,因此您可能会遇到线程之间更改的可见性问题。
有许多方法可以使它线程安全。请注意,版本(1)、(2)和(4)将阻止其他线程通过B执行点执行B,直到B执行完成为止。
1)已经提到的std::call_once
void A() {
    static std::once_flag execute_B;
    std::call_once(flag1, [this](){ B(); });
}2)初始化静态变量时调用B:
void A() {
    static bool dummy = [this](){ B(); return true; });
}3)使用原子交换:
void A() {
    static std::atomic<bool> execute_B = true;
    if(execute_B.exchange(false, std::memory_order_acq_rel))
        B();
}4)用互斥保护止回阀(为了避免以后性能退化,请使用双重检查锁):
void A() {
    static std::mutex m_;
    static std::atomic<bool> execute_B = true;
    if(execute_B.load(std::memory_order_acquire)) {
        std::unique_lock<std::mutex> lk(m_);
        if(execute_B.load(std::memory_order_relaxed)) {
            B();
            execute_B.store(false, std::memory_order_release);
        }
    }
}https://stackoverflow.com/questions/38324908
复制相似问题