2013-08-22 94 views
0

boost :: call_once是如何实现的?通过双重检查锁定模式实现call_once

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

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

+0

你知道“双重检查锁定模式”也是白搭? –

+0

我不会POCO线程 –

+0

问题是我需要在多线程环境中实现单例模式。我对双重检查锁定模式(及其低效率)和boost call_once做了一些分析。我不应该使用boost库。所以我需要一个实现。 –

回答

1

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

与注释部分中声称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(); 
} 
相关问题