C++实现一个线程安全的单例工厂实现代码

  C++实现一个线程安全的单例工厂实现代码

我们见到经常有人用 static 局部对象的方式实现了类似单例模式,最近发现一篇文章明确写明 编译器在处理  static局部变量的时候 并不是线程安全的 !!!

http://blogs.msdn.com/b/oldnewthing/archive/2004/03/08/85901.aspx

于是实现了一个单例工厂  并且是线程安全的

#ifndef SINGLETONFACTORY_H
#define SINGLETONFACTORY_H
#include "windows.h"
#include <memory>
namespace Tools
{
template<class T>class SingletonFactory
{
public:
  virtual ~SingletonFactory()
  {
   ::DeleteCriticalSection(&__criticalSection);
  }
  std::auto_ptr<T>& GetInstance();
  static SingletonFactory<T>* CreateSingletonFactory();
private:
  SingletonFactory()
  {
    ::InitializeCriticalSection(&__criticalSection);
  }
  std::auto_ptr<T> __singletonObj;
  CRITICAL_SECTION __criticalSection;
}; 

//初始化创建 后续在多线程中使用
//还有另一种写法是单独的函数直接返回内部单例包装静态成员在 多线程情况下不安全
//SingletonFactory::CreateSingletonFactory().GetInstance();
template<class T> SingletonFactory<T>* SingletonFactory<T>::CreateSingletonFactory(){
  static SingletonFactory<T> temObj;
  return &temObj;
}
//工厂实例
template<class T> std::auto_ptr<T>& SingletonFactory<T>::GetInstance()
{
  if(__singletonObj.get()==0)
  {
    ::EnterCriticalSection(&__criticalSection);
    if(__singletonObj.get()==0)
      __singletonObj=std::auto_ptr<T>(new T);
    ::LeaveCriticalSection(&__criticalSection);
  }
  return __singletonObj;
}
} 

#endif // SINGLETONFACTORY_H

测试代码

SingletonFactory<Data1>*singleton1=SingletonFactory<Data1>::CreateSingletonFactory();
singleton1->GetInstance()->x=100;
cout<<singleton1->GetInstance()->x<<endl;
singleton1->GetInstance()->y=200;
cout<<singleton1->GetInstance()->x<<endl;
cout<<singleton1->GetInstance()->y<<endl; 

SingletonFactory<Data2>*singleton2=SingletonFactory<Data2>::CreateSingletonFactory();
singleton2->GetInstance()->x=100;
cout<<singleton2->GetInstance()->x<<endl;
singleton2->GetInstance()->y=200;
cout<<singleton2->GetInstance()->x<<endl;
cout<<singleton2->GetInstance()->y<<endl;

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • 从C++单例模式到线程安全详解

    先看一个最简单的教科书式单例模式: class CSingleton { public: static CSingleton* getInstance() { if (NULL == ps) {//tag1 ps = new CSingleton; } return ps; } private: CSingleton(){} CSingleton & operator=(const CSingleton &s); static CSingleton* ps; }; CSingleton*

  • C++使用CriticalSection实现线程同步实例

    本文实例讲述了C++使用CriticalSection实现线程同步的方法,在前文C++线程同步实例分析的基础上增加了四行代码,使用了四个函数: EnterCriticalSection ::DeleteCriticalSection ::EnterCriticalSection ::LeaveCriticalSection此时,打印出来的数字就相等了. 具体代码如下: #include "stdafx.h" #include <Windows.h> DWORD g_cnt1

  • c++实现简单的线程池

    这是对pthread线程的一个简单应用 1.      实现了线程池的概念,线程可以重复使用. 2.      对信号量,互斥锁等进行封装,业务处理函数中只需写和业务相关的代码. 3.      移植性好.如果想把这个线程池代码应用到自己的实现中去,只要写自己的业务处理函数和改写工作队列数据的处理方法就可以了. Sample代码主要包括一个主程序和两个线程实现类 ThreadTest.cpp:主程序 CThreadManager:线程管理Class,线程池的实现类 CThread:线程Class

  • linux下的C\C++多进程多线程编程实例详解

    linux下的C\C++多进程多线程编程实例详解 1.多进程编程 #include <stdlib.h> #include <sys/types.h> #include <unistd.h> int main() { pid_t child_pid; /* 创建一个子进程 */ child_pid = fork(); if(child_pid == 0) { printf("child pid\n"); exit(0); } else { print

  • 老生常谈C++的单例模式与线程安全单例模式(懒汉/饿汉)

    1 教科书里的单例模式 我们都很清楚一个简单的单例模式该怎样去实现:构造函数声明为private或protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实例的动作由一个public的类方法代劳,该方法也返回单例类唯一的实例. 上代码: class singleton { protected: singleton(){} private: static singleton* p; public: static singleton* instance()

  • C++程序中启动线程的方法

    C++11 引入一个全新的线程库,包含启动和管理线程的工具,提供了同步(互斥.锁和原子变量)的方法,我将试图为你介绍这个全新的线程库. 如果你要编译本文中的代码,你至少需要一个支持 C++11 的编译器,我使用的是 GCC 4.6.1,需要使用 -c++0x 或者 -c++11 参数来启用 C++11 的支持. 启动线程 在 C++11 中启动一个线程是非常简单的,你可以使用 std:thread 来创建一个线程实例,创建完会自动启动,只需要给它传递一个要执行函数的指针即可,请看下面这个 Hel

  • C++实现多线程查找文件实例

    主要是多线程的互斥 文件 的查找 多线程互斥的框架 复制代码 代码如下: //线程函数  UINT FinderEntry(LPVOID lpParam)  {      //CRapidFinder通过参数传递进来       CRapidFinder* pFinder = (CRapidFinder*)lpParam;      CDirectoryNode* pNode = NULL;      BOOL bActive = TRUE; //bActive为TRUE,表示当前线程激活   

  • C++ 线程(串行 并行 同步 异步)详解

    C++  线程(串行 并行 同步 异步)详解 看了很多关于这类的文章,一直没有总结.不总结的话就会一直糊里糊涂,以下描述都是自己理解的非官方语言,不一定严谨,可当作参考. 首先,进程可理解成一个可执行文件的执行过程.在ios app上的话我们可以理解为我们的app的.ipa文件执行过程也即app运行过程.杀掉app进程就杀掉了这个app在系统里运行所占的内存. 线程:线程是进程的最小单位.一个进程里至少有一个主线程.就是那个main thread.非常简单的app可能只需要一个主线程即UI线程.

  • C++封装线程类的实现方法

    本文实例讲述了C++封装线程类的实现方法.分享给大家供大家参考.具体方法如下: 复制代码 代码如下: // 给主窗口的通知消息  #define WM_CUTTERSTART WM_USER + 100    // wParam == xxx  lParam==xxxx    /*  外面调用这个类时,只需要IsRunning() Startxxx(xxx) Suspendxxx()   Resumexxx() Stopxxx()  */    /*  m_bContinue在真正的工作代码Do

  • C++实现一个线程安全的单例工厂实现代码

      C++实现一个线程安全的单例工厂实现代码 我们见到经常有人用 static 局部对象的方式实现了类似单例模式,最近发现一篇文章明确写明 编译器在处理  static局部变量的时候 并不是线程安全的 !!! http://blogs.msdn.com/b/oldnewthing/archive/2004/03/08/85901.aspx 于是实现了一个单例工厂  并且是线程安全的 #ifndef SINGLETONFACTORY_H #define SINGLETONFACTORY_H #in

  • Golang基于sync.Once实现单例的操作代码

    目录 基于sync.Once实现单例 单例类型定义Driver 类Field conn once.Do(func() {}) 并发访问once.Do() 对外暴露方法Conn() 重新new(Driver)会发生什么? 在go里实现单例模式有多种方式: 基于lock 基于init函数 基于sync.Once 本文介绍基于sync.Once的方式来实现单例,熟练掌握这种模式,并理解其底层原理,对大部分人来讲已经完全够用了. 基于sync.Once实现单例 // 其他package也可见,在其他地方

  • Java正确实现一个单例设计模式的示例

    设计模式中的单例,是最常用,也算是比较简单的一个了.我们都知道,要想保证只有一个实例,通常采用加锁和双重检查的方式来实现单例,代码如下. public class SingletonTest { private SingletonTest(){ } private static SingletonTest instance; public static SingletonTest getInstance(){ if(instance == null){ synchronized (Singlet

  • spring中向一个单例bean中注入非单例bean的方法详解

    目录 前言 错误实例演示 实现ApplicationContextAware接口 lookup method lookup method签名 总结 前言 看到这个题目相信很多小伙伴都是懵懵的,平时我们的做法大都是下面的操作 @Component public class People{ @Autowired private Man man; } 这里如果Man是单例的,这种写法是没有问题的,但如果Man是原型的,这样是否会存在问题. 错误实例演示 这里有一个原型(生命周期为prototype)的

  • Java的单例设计模式详解

    1.什么是单例模式 生成一个独一无二的,保证任何时刻一个类只有一个实例的模式 确保一个类只有一个实例,并提供一个全局访问点 可以在需要时才创建对象,避免了全局变量在程序启动时就得创建对象的缺点. 2.经典单例模式实现 public class MyInstance{ //第一步:私有化构造器,只有类自身才能调用构造器外部类不能够直接new出这个类的实例对象 private MyInstance(){} //第二步:声明一个全局静态变量来记录自身实例的对象,也是私有的,限制其它外部类访问 priv

  • Java单例的写法详解

    目录 饿汉式 懒汉式一 懒汉式二 懒汉式三(双重检查) 静态内部类 枚举 总结 单例模式,顾名思义,就是全局只保存有一个实例并且能够避免用户去手动实例化,所以单例模式的各种写法都有一个共同点,不能通过new关键字去创建对象,因此,如果能够通过构造方法实例化,那么就一定要将其声明为私有. 饿汉式 public class PersonResource { public static final PersonResource PERSON_RESOURCE_SINGLETON = new Perso

  • JavaScript编程的单例设计模讲解

    在Javascript中,单例模式是一种最基本又经常用到的设计模式,可能在不经意间就用到了单例模式. 本文将从最基础的理论开始,讲述单例模式的基本概念和实现,最后用一个例子来讲述单例模式的应用. 理论基础 概念 单例模式,顾名思义就是只有一个实例存在.通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源.如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案. 基本结构 最简单的单例模式起始就是一个对象字面量,它将有关联的属性和方

  • Python 用__new__方法实现单例的操作

    介绍 init 方法通常用在初始化一个类实例时候,但其实它不是实例化一个类的时候第一个被调用 的方法.当使用 Student(id, name) 这样的表达式来实例化一个类时,最先被调用的方法 其实是 new 方法. new方法接受的参数虽然也是和init一样,但init是在类实例创建之后调用,而 new方法正是创建这个类实例的方法. new为对象分配空间,是内置的静态方法,new在内存中为对象分配了空间也返回了对象的引用,init获得了这个引用才初始化这个实例. 示例 一个非常简单的单例 cl

  • C++使用智能指针实现模板形式的单例类

    本文通过实例为大家分享了java实现图书管理系统的具体代码,供大家参考,具体内容如下 实现一个模板形式的单例类,对于任意类型的类经过Singleton的处理之后,都能获取一个单例对象,并且可以传递任意参数 并且还使用了智能指针,把生成的单例对象托管给智能指针,从而实现自动回收单例对象的资源 此外,如果需要一个放在静态成员区的对象供其他类使用,又不希望修改原有的类的代码,这时候可以通过该模板套一层壳,形成单例对象. 头文件 template_singleton.hpp #include <iost

  • Spring中Bean的单例和多例使用说明

    目录 Bean的单例和多例使用 实战演示 Spring单例bean与原型bean区别和创建过程 singletonScope与prototypeScope Bean的单例和多例使用 在Spring中,bean可以被定义为两种模式:prototype(多例)和singleton(单例) singleton(单例):只有一个共享的实例存在,所有对这个bean的请求都会返回这个唯一的实例. prototype(多例):对这个bean的每次请求都会创建一个新的bean实例,类似于new. Spring

随机推荐