#include <iostream>
#include <thread>
#include <atomic>
#include <mutex>
#include <future>
#include <vector>
#define ATOMIC
#ifdef CALLONCE
std::once_flag f;
#endif
class Singleton;
inline Singleton *GetNullptr( void ){
return ( Singleton *)nullptr;
}
class Singleton{
class dtor{
public:
~dtor( void ){
puts( "Dtor Called ");
if( Singleton::m_instance )
delete Singleton::m_instance;
Singleton::m_instance = nullptr;
}
};
private:
Singleton( void ) { puts("Singleto default constructor called"); };
public:
~Singleton( void ){ puts( "Singleto default destructor called" ); }
explicit Singleton( const Singleton& ) = delete;
Singleton( Singleton&& ) = delete;
Singleton& operator=( const Singleton& ) = delete;
Singleton& operator=( Singleton&& ) = delete;
static Singleton& getInstance( void ){
#ifdef ATOMIC
Singleton *t = m_instance.load( std::memory_order_relaxed );
std::atomic_thread_fence( std::memory_order_acquire );
if( !t ){
std::lock_guard< std::mutex > locker( m_mutex );
std::cout << "A thread hold the mutex and lock it" << std::endl;
t = m_instance.load( std::memory_order_relaxed );
if( !t ){
t = new Singleton;
static dtor d;
std::atomic_thread_fence( std::memory_order_relaxed );
}
}
if( t ) m_instance = t;
return *m_instance;
#elif defined CALLONCE
std::call_once( f, [&]{ Singleton::CreateInstance(); } );
return *m_instance;
#endif
}
protected:
static std::atomic< Singleton * > m_instance;
#ifdef CALLONCE
static inline void CreateInstance( void ){
std::unique_lock< std::mutex > m_mutex;
m_instance = new Singleton;
static dtor d;
}
#endif
private:
static std::mutex m_mutex;
};
std::mutex Singleton::m_mutex;
std::atomic< Singleton * > Singleton::m_instance( GetNullptr() );
int main( void ){
int counter { 1000 };
std::vector< std::future< void > > futrVec;
while( counter-- ) futrVec.push_back( std::move( std::async( []{
Singleton::getInstance(); })
));
for( auto& futr : futrVec ) futr.wait();
puts( "All instance generating test done");
return 0;
}
【设计模式:singleton pattern】
最新推荐文章于 2024-10-04 19:09:21 发布