singleton-多线程下Singleton模式

问题描述

多线程下Singleton模式
 //singleton.h

#ifndef _SINGLETON_H_
#define _SINGLETON_H_

#include "synobj.h"

template<typename T>
class Singleton
{
public:
    static T* Instance();

protected:

private:
    Singleton();
    ~Singleton();
    Singleton(Singleton& );
    Singleton& operator = (Singleton& );
    static void Destory();

private:
    static T*  _instance;
    static Mutex _mutex;
};
 //singleton.cpp

//volatile的作用是: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值.

#include "stdafx.h"
#include "singleton.h"
#include <iostream>
#include <stdlib.h>

using namespace std;

template<typename T> T*  Singleton<T>::_instance = NULL;
template<typename T> Mutex Singleton<T>::_mutex;

template<typename T>
Singleton<T>::Singleton()
{

}

template<typename T>
Singleton<T>::~Singleton()
{

}

template<typename T>
T* Singleton<T>::Instance()
{
    if(_instance == NULL )
    {
        Lock lock(_mutex);
        if(_instance == NULL)
        {
            T* temp = new T;
            _instance = temp;
            //_instance = new T();
            atexit(Destory);
        }
    }
    return _instance;
}

template<typename T>
void Singleton<T>::Destory()
{
    if(NULL != _instance)
    {
        delete _instance;
        _instance = NULL;
    }
}
 // Singleton20.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "singleton.h"
#include "synobj.h"
#include <stdio.h>
#include <iostream>

using namespace std;

class A:public Singleton<A>
{
public:
    void DoSomething()
    {
        cout<<"hello DoSomething"<<endl;
    }

};

int _tmain(int argc, _TCHAR* argv[])
{
    A* a = A::Instance();
    a->DoSomething();

    getchar();
    return 0;
}


我的代码大致是这样的,各位前辈们,帮忙分析一下我的错误吧。。。。

解决方案

用模板类的实现应该写在.h里面,最好是将.h命名成.hpp,你看看boost里面的头文件基本都是.hpp
这个其实是因为模板在编译的时候并没有实例化,看下这个文章吧c++模板类(一)理解编译器的编译模板过程

解决方案二:

http://blog.chinaunix.net/xmlrpc.php?r=blog/article&id=4281275&uid=26611383

解决方案三:

http://blog.csdn.net/scutth/article/details/7997685

解决方案四:

vs应该不支持模版分离,你把模版定义,实现都放在一起。

解决方案五:

http://www.cnblogs.com/08shiyan/archive/2012/03/16/2399617.html

解决方案六:

你用的什么编译器版本,VC6? 请用最新的编译器VS2012等。老版本编译器有问题。

然后就是析构函数最好用虚函数

virtual ~Singleton(){};

解决方案七:

SingleTon模式的多线程环境
多线程Singleton单件模式
多线程Singleton单件模式

解决方案八:

我来顶一下,各位前辈帮忙看看吧。。。。。

解决方案九:

将声明和定义都放在一起后,发现还是有一个小小的问题,不知道为什么?请大家帮忙再看一下吧

 //singleton.h

#ifndef _SINGLETON_H_
#define _SINGLETON_H_

#include "synobj.h"
#include <stdlib.h>

template<typename T>
class Singleton
{
public:

    static T* Instance()
    {

        if(NULL == _instance)
        {
            Lock lock(_mutex);
            if(NULL == _instance)
            {
                T* temp = new T;
                _instance = temp;
                atexit(Destory);
            }
        }
        return _instance;
    }

protected:

private:
    Singleton(){}
    ~Singleton(){}
    Singleton(Singleton& ){}
    Singleton& operator = (Singleton& ){}
    static void Destory()
    {
        if(NULL != _instance)
        {
            delete _instance;
            _instance = NULL;
        }
    }

private:
    static T*  _instance;
    static Mutex _mutex;
};

template<typename T> T* Singleton<T>::_instance = NULL;
template<typename T> Mutex Singleton<T>::_mutex;
 // Singleton20.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "singleton.h"
#include "synobj.h"
#include <stdio.h>
#include <iostream>

using namespace std;

class A:public Singleton<A>
{
public:
    void DoSomething()
    {
        cout<<"hello DoSomething"<<endl;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    A* a = A::Instance();
    a->DoSomething();

    getchar();
    return 0;
}

解决方案十:

将类模板的构造函数和析构函数的声明和定义放在public下面,就可以测试通过了,可是这是为什么呢?

时间: 2024-08-31 01:29:19

singleton-多线程下Singleton模式的相关文章

Python下singleton模式的实现方法_python

很多开发人员在刚开始学Python 时,都考虑过像 c++ 那样来实现 singleton 模式,但后来会发现 c++ 是 c++,Python 是 Python,不能简单的进行模仿. Python 中常见的方法是借助 global 变量,或者 class 变量来实现单件.本文就介绍以decorator来实现 singleton 模式的方法.示例代码如下: ##----------------------- code begin ----------------------- # -*- cod

如何使用线程局部存储实现多线程下的日志系统

概述 通常来说,在应用程序中需要日志来记录程序运行的状态,以便后期问题的跟踪定位.在日志系统的设计中,通常会有一个总的日志系统来统一协调这些日志的设置如位置.输出级别和内容等.在多线程编程中,当每个线程都需要输出日志时,因为要考虑线程间的同步,日志系统的设计更加复杂. 在单线程应用程序中,通常使用一个日志单例向某个文件输出应用运行过程中的重要日志信息,但是在多线程环境中,这样做显然不好,因为各个线程打印出的日志会错综复杂从而使得日志文件不容易阅读和跟踪.比较好的办法是主线程记录自己的日志,各个子

切换ubuntu下图形模式与linux命令行模式

  本文讲述了linux下图形模式与linux命令行模式切换要领.下面将对此执行 细致说明: ctrl+alt+f2 命令行模式 ctrl+alt+f7 图形模式 我安装的是ubuntu版本,其他版本是不是这样没有研究过. 下面是开机要进入linux命令行哪种模式的设定:(我在我装的ubuntu里看了下没有inittab文件,真奇怪) $gedit /etc/inittab 例如,把id:5:initdefault中的5改为3 ,就是linux进入系统时,原来是直接进入x界面模式的,现在就直接进

浅析Python多线程下的变量问题

  这篇文章主要介绍了Python多线程下的变量问题,由于GIL的存在,Python的多线程编程问题一直是开发者中的热点话题,需要的朋友可以参考下 在多线程环境下,每个线程都有自己的数据.一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁. 但是局部变量也有问题,就是在函数调用的时候,传递起来很麻烦: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 def process_student(name): std =

ASP.NET多线程下使用HttpContext.Current为null解决方案

问题一:多线程下获取文件绝对路径   当我们使用HttpContext.Current.Server.MapPath(strPath)获取绝对路径时HttpContext.Current为null,解决办法如下:        ///          /// 获得当前绝对路径         ///          /// 指定的路径         /// 绝对路径         public static string GetMapPath(string strPath)       

java中多线程下静态connection的问题

问题描述 java中多线程下静态connection的问题 普遍观点是不要使用静态的连接,但是--我面临的需求情况是1.数据只查不改2.该连接只在用户登陆时使用,而其他过程有单独的连接池(与登录不是一个库),用池觉得浪费3.可能在同一时间有几千人同时登陆,而一天内的其他时间登录次数很少.以下是部分代码: public class CWJdbcConnection { private static Map<String String> map = new GetFile().getFile(Fc

使用READDIR和多线程下的READDIR_R读取目录

书上只说了用第一个函数在多线程下会不安全, 为什么不安全,也没有说,只是取嘛,现在想不太通. 是为记.. 1 [root@localhost ccode]# cat readdir_exp.c 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <dirent.h> 5 6 int main(int argc, char *argv[]) 7 { 8 DIR *dirp; 9 struct dirent *dp;

qt-关于QT多线程下的connect问题

问题描述 关于QT多线程下的connect问题 我用QT生成的ui界面中生添加了按钮A,我想在点击按钮A后,用自定义的线程去执行 A的槽函数,或者是用自定义的线程去监听A的点击事件,然后再去执行A的槽函数, 新手,求解,谢谢! 解决方案 1.定义按钮响应槽函数,并connect到该槽函数: 2.创建一个线程: 3.在槽函数中向线程推送要执行的任务,然后槽函数返回. 解决方案二: vector tasks; void ThreadFunc() { while(1) { for( int i=0;

Java中对AtomicInteger和int值在多线程下递增操作的测试_java

Java针对多线程下的数值安全计数器设计了一些类,这些类叫做原子类,其中一部分如下: java.util.concurrent.atomic.AtomicBoolean; java.util.concurrent.atomic.AtomicInteger; java.util.concurrent.atomic.AtomicLong; java.util.concurrent.atomic.AtomicReference; 下面是一个对比  AtomicInteger 与 普通 int 值在多线