首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >嵌套函数的线程安全和唯一执行

嵌套函数的线程安全和唯一执行
EN

Stack Overflow用户
提问于 2016-07-12 09:27:59
回答 1查看 235关注 0票数 1

我有一个类MyClass,它的函数A多次并行执行。然后,函数B只应该执行一次。我的初始设置看起来很简单,但我怀疑它是否是线程安全的。我怎么才能保证线程安全?我在用C++11。

代码语言:javascript
复制
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";
        }
};
EN

回答 1

Stack Overflow用户

发布于 2016-07-12 09:38:20

是的,您的代码是不安全的:在if语句的正文中有几个线程可以进入,然后execute_B才会被设置为false。而且,execute_B不是原子的,因此您可能会遇到线程之间更改的可见性问题。

有许多方法可以使它线程安全。请注意,版本(1)、(2)和(4)将阻止其他线程通过B执行点执行B,直到B执行完成为止。

1)已经提到的std::call_once

代码语言:javascript
复制
void A() {
    static std::once_flag execute_B;
    std::call_once(flag1, [this](){ B(); });
}

2)初始化静态变量时调用B

代码语言:javascript
复制
void A() {
    static bool dummy = [this](){ B(); return true; });
}

3)使用原子交换:

代码语言:javascript
复制
void A() {
    static std::atomic<bool> execute_B = true;
    if(execute_B.exchange(false, std::memory_order_acq_rel))
        B();
}

4)用互斥保护止回阀(为了避免以后性能退化,请使用双重检查锁):

代码语言:javascript
复制
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);
        }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38324908

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档