• 单例模式-通用写法1


    首先,基于懒汉式写法,基于线程安全,因此,需要加锁,具体如下:

    1.互斥锁写成类,实现自动加锁和解锁(criticalSection.h)

    #ifndef __criticalSection_h__INCLUDED__
    #define __criticalSection_h__INCLUDED__
    #include <errno.h>              // EBUSY...and the other errnos
    
    extern "C"
    {
    #include <pthread.h>            // pthread_mutex_t
    }
    
    
    namespace cmn
    {
    
    class PThreadMutex
    {
    public:
    
    explicit PThreadMutex(
        pthread_mutex_t & mutex_r
        ):
        isAcquired_m( false ),
        mutex_rm    ( mutex_r )
    {
        beginCriticalSection();
    };
    
    virtual ~PThreadMutex()
    {
        endCriticalSection();
        if ( isAcquired_m )
        {
            // endCriticalSection() failed.  This is a serious
            // error.
            return;
        }
    };
    
    void beginCriticalSection()
    {
        int result = pthread_mutex_lock( &mutex_rm );
    
        switch ( result )
        {
        case 0:       // success
        {
            isAcquired_m = true;
            return;
        }
        case EINVAL:  // not initialized
        case EDEADLK: // already locked by this thread
        default:      // should never happen
        {
            // TODO SOFTWARE1(result);
            isAcquired_m = false;
            return;
        }}
    
    }//beginCriticalSection
    
    void endCriticalSection()
    {
        if (!isAcquired_m)
        {
            return;
        }
        int result = pthread_mutex_unlock( &mutex_rm );
        switch ( result )
        {
            case 0:       // success
            {
                isAcquired_m = false;
                return;
            }
            case EINVAL:  // not initialized
            case EPERM:   // not locked by this thread
            default:      // should never happen
            {
                // TODO SOFTWARE1(result);
                return;
            }
        }
    
    }//endCriticalSection
    
    private:
    
        bool              isAcquired_m;
        pthread_mutex_t & mutex_rm;
    
    }; //PThreadMutex
    
    };// namespace cmn
    
    #endif //__criticalSection_h__INCLUDED__

    2. 懒汉式单例模式(singletonHolder.h)

    #ifndef __singletonHolder_h__INCLUDED__
    #define __singletonHolder_h__INCLUDED__
    #include "criticalSection.h"      // cmn::PThreadMutex
    
    namespace cmn
    {
       template < class T >
       class SingletonHolder
       {
       public:
          static T & getInstance();
          // deleteInstance() shoule be used for debugging only.
    
          // Calling this will "empty" the singleton, however a subsequent call
          // to getInstance will recreate a brand new singleton.
    
          static void deleteInstance();
    
       private:
          // prevent accidental construction
          SingletonHolder( );
          SingletonHolder( const SingletonHolder & );
    
          static T * volatile instance_spm;
    
       public:
          static pthread_mutex_t mutex_sm;
    
       };
    
       template < class T >
       T & SingletonHolder<T>::getInstance()
       {
          // use the "double checked locking pattern"
          if ( !instance_spm )
          {
             cmn::PThreadMutex lock(mutex_sm);
             if ( !instance_spm )
             {
                instance_spm = new T;
             }
          }
          return *instance_spm;
    
       }//getInstance
    
       template < class T >
       void SingletonHolder<T>::deleteInstance()
       {
          // use the "double checked locking pattern"
          if ( instance_spm )
          {
             cmn::PThreadMutex lock(mutex_sm);
             if ( instance_spm )
             {
                delete instance_spm;
                instance_spm = 0;
             }
          }
    
       }//deleteInstance
    
    
    // We want to define a macro for use of this template. Mainly to simplify
    // the declaration of the static members...
    #define SINGLETON_HOLDER_INIT( name ) 
       template class cmn::SingletonHolder<name>; 
       template<> name* volatile cmn::SingletonHolder<name>::instance_spm = 0; 
       template<> pthread_mutex_t cmn::SingletonHolder<name>::mutex_sm 
                    = PTHREAD_MUTEX_INITIALIZER;
    
    
    } // namespace cmn
    
    #endif //__singletonPerProcess_h__INCLUDED__

    测试代码如下:

    #include <iostream>
    #include "singletonHolder.h"
    #include "criticalSection.h"
    
    using namespace std;
    class Server;
    #define mdfServer_s ServerHandle::getInstance()
    typedef cmn::SingletonHolder<Server> ServerHandle;
    SINGLETON_HOLDER_INIT(Server)
    class Server
    {
    public:
        friend class cmn::SingletonHolder<Server>;
         void print(){cout<<i<<endl;}
    private:
        Server();
        ~Server();
        int i ;
    };
    
    Server::Server():i(0){}
    
    Server::~Server(){}
    
    int main()
    {
        (void)mdfServer_s;
        mdfServer_s.print();
        return 0;
    }

    结果输出:0

  • 相关阅读:
    QLPreviewController来预览文件
    Camera360SDK
    实现 JSON + Jquery+.Net ajax功能
    showModalDialog传值
    web方式AJAX调用
    CRM4.0多个实体关联查询
    用javascript 动态添加部门和人员
    GridView中使用超连接
    根据订单号查询出订单附属实体
    sql 常用聚合函数
  • 原文地址:https://www.cnblogs.com/bwbfight/p/14559135.html
Copyright © 2020-2023  润新知