c++ - call_once 通过双重检查锁定模式实现

标签 c++ qt boost poco-libraries

boost::call_once 是如何实现的?

这个是否使用双重检查锁定模式?

Qt 或 POCO 库中是否有任何等效的实现?

最佳答案

我偶然发现了这个老问题.. 4 年后,您的案例可能不再有趣,但我相信示例实现可能仍然具有一定的值(value)。

与评论部分声称 DCLP 已损坏相反,这在 C++11 中不再成立,因为它提供了必要的原子类型、操作和内存屏障。

这是一个最小的实现,不一定是 boost 实现。忽略异常行为。
my_call_once 的参数函数保证被调用不超过一次并且共享数据在线程之间正确同步..就像真实的 std::call_once

#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>

class my_once_flag {
    std::mutex mtx;
    std::atomic<bool> flg{false};

    template<typename Func, typename... Args>
    friend void my_call_once(my_once_flag&, Func&&, Args&&...);
};

template<typename Func, typename... Args>
void my_call_once(my_once_flag& flag, Func&& f, Args&&... args)
{
    if (flag.flg.load(std::memory_order_acquire) == false)
    {
        std::lock_guard<std::mutex> lck{flag.mtx};

        if (flag.flg.load(std::memory_order_relaxed) == true)
            return;

        std::forward<Func>(f)(std::forward<Args>(args)...);

        flag.flg.store(true, std::memory_order_release);
    }
}

void just_once(int i) { std::cout << "once " << i << std::endl; }

int main()
{
    my_once_flag of;

    std::thread {[&]{ my_call_once(of, just_once, 1); }}.join();
    std::thread {[&]{ my_call_once(of, just_once, 2); }}.join();
}

关于c++ - call_once 通过双重检查锁定模式实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18389091/

相关文章:

c++ - Qt 2D 寻路游戏中的动画

qt - 在 *.pro 文件之间传递变量

c++ - 使用其他函数中的变量进入主函数C++

c++ - 简单的 lambda 表达式 C++03 不带 boost 等

c++ - 无法从套接字中正确读取

c++ - Boost::iostreams::filtering_istreams 等待 E.O.F

c++ - boost 进程间内存分配缓慢

c++ - Boost Type Erasure的实践与发现

c++ - 使用 C++ 和 Visual Studio 2008 的 MFC DLL

c++ - QList<QString> 运算符<<