使用 std::atomic 进行一次执行

Using std::atomic for once-only execution

提问人:Kostya Vasilyev 提问时间:3/12/2023 最后编辑:Kostya Vasilyev 更新时间:3/12/2023 访问量:147

问:

我使用这样的一段代码只执行一次:

class Test {
public:
    void foo() {
        if (m_barrier.exchange(true)) {
            return;
        }

        // This should only execute once
    }
private:
    std::atomic<bool> m_barrier { false };
};

该函数由多个线程多次调用,但下面的代码只能执行一次(每个对象实例)。fooexchange

我以为这是正确的代码 - 直到昨天我发现有时下面的代码执行不止一次。exchange

这是在 Android 上,CPU aarch64,所以可能是 Android 特定的错误,它发生在三个不同的手机上 - 或者更有可能是我遗漏了一些东西,代码不能保证只执行一次?std

请不要建议使用,我不能在这里使用,因为...原因。std::once

更新:是的,我可以用非原子代替它,这是可以理解的,问题是为什么线程不安全。std::mutexboolstd::atomic

Android C++ 多线程标准

评论

0赞 user17732522 3/12/2023
在我看来是正确的。也许是其他地方的错误,例如写出越界的东西?m_barrier
1赞 The Dreams Wind 3/12/2023
该成员不是静态的,您可能只是从多个对象调用函数m_barrier
1赞 Pete Becker 3/12/2023
@WBuck -- 是原子的;当从多个线程访问时,它具有明确定义的语义。是的,您可以用更重的同步对象替换它,但问题中没有任何内容(到目前为止)表明这是合适的。m_barrier
2赞 Pete Becker 3/12/2023
如果任何线程依赖于测试后代码的任何副作用,那么你就会遇到数据争用。 保证调用 once-function 的每个线程都将看到 once-function 的所有副作用和正确的返回值。此代码也不能保证。不知道这是否是此功能预期用途的问题,但这肯定是一个潜在的陷阱。std::once
1赞 WBuck 3/12/2023
更不用说,使用常规锁的认知开销要少得多。

答: 暂无答案