`

C++多线程的Singleton(2)

阅读更多

C++多线程的Singleton(1)

 

如果你的系统有读写锁,恭喜你,也许你可以比较方便的解决这个问题。你可以这么写:

// Singleton.h
class Singleton
{
  public:
     ~Singleton(){}
     static Singleton& getInstance();

  private:
     Singleton(){}
     static RWLock rwlock_;
};

// Singleton.cpp

/* static */
Lock Singleton::lock_;

Singleton& Singleton::getInstance()
{
  static Singleton *instance = NULL;
  rwlock.rdlock(); 
  if (NULL == instance) // thread B Pos1
  {
    rwlock.unlock();
    {
      WLockGuard wguard(rwlock);
  if (NULL == instance) 
      {
          instance = new Singleton;  // thread A   Pos2
       }
       return instance;
    }
  }
  rwlock.unlock();
  return &instance;
} 

 这段代码没有符合一个return的原则,之所以这么写是因为singleton的构造函数有可能会有异常,那么这么封装,可以最大程度的保证不会死锁。这段代码比上一段已经有很大程度的改变了。首先,当instance初始化之后,以后就全部是读锁了,只有一个简单函数的开销(相对被mutex锁住切换context的开销,一个函数的调用要小多了,这个函数不是指rwlock.rdlock(),因为这个函数本身100%是inline的;而是指pthread_rwlock_rdlock这样的函数调用)。但是大家也许已经发现了,如果在很多线程同时初始化这个instance的时候,还是会有等待锁的情况发生。那有没有办法解决这个问题呢?答案是可以的,不过需要用到一些同步原语,包括Atomic和Memory Barrier。我不会再写去了,因为我觉得这些高级的功能,我们一定要抵制这种诱惑。因为如果用这些你的代码会有以下两个缺点:

(1)可读性较差

(2)移植性较差(你可以写很多宏来帮助你在不同平台不同CPU上使用,譬如Chrome)

如果你有兴趣,请察看chrome的源代码的Base/singleton的实现。

 

分享到:
评论

相关推荐

    C++完美实现Singleton模式

    1. **线程安全**:在多线程环境下,如果多个线程同时尝试创建Singleton实例,可能会导致创建多个对象。为了保证线程安全,通常需要在`Instance()`方法中添加互斥锁(`mutex`)或者使用原子操作(`std::atomic`)。...

    C++ 实现的singleton 模式

    在多线程环境中,如果没有适当的同步机制,`getInstance()`可能会在不同线程中同时创建多个实例。在C++11及更高版本中,我们可以使用`std::call_once`和`std::once_flag`来确保实例只在第一次调用时创建: ```cpp #...

    C++中多线程与Singleton的那些事儿

    前言  前段时间在网上看到了个的面试题,大概...本文主要将从基本的单线程中的Singleton开始,慢慢讲述多线程与Singleton的那些事。  单线程  在单线程下,下面这个是常见的写法: template class Singleton

    使用C++11实现线程安全的单例模式

    在C++11之前,C++标准并不直接支持多线程编程。C++11引入了 `<thread>` 头文件,提供了线程创建、同步等机制,使开发者能够编写多线程程序。`std::mutex` 是一个互斥锁,用于保护共享资源,确保同一时间只有一个线程...

    c++线程安全日志类

    1. **线程安全**:在多线程环境中,多个线程可能会同时访问和修改同一个资源,这可能导致数据不一致或竞态条件。为了解决这个问题,我们的日志类应该实现线程安全的写入操作。这通常通过互斥锁(mutex)或原子操作...

    C++类中创建多线程实现本地和远程打印

    2. **线程同步与通信**:为了确保数据安全和避免竞态条件,多线程程序通常需要使用互斥量(`std::mutex`)、条件变量(`std::condition_variable`)或者信号量(`std::semaphore`)等工具进行同步。在`print.cpp`中...

    Linux多线程服务端编程:使用muduo C++网络库

    《Linux多线程服务端编程:使用muduo C++网络库》主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。...

    单例实现源码singleton-C++

    总结来说,C++中的单例模式实现多种多样,选择哪种方式取决于具体的应用场景,如是否考虑多线程、内存占用、初始化时机等。通过理解这些实现方式,我们可以更好地设计和使用单例模式,以满足软件的高效、稳定和灵活...

    17_懒汉式多线程同步优化.zip_C++

    在C++编程中,多线程同步是一个关键的议题,特别是在设计高效的并发程序时。"懒汉式"多线程同步是一种延迟初始化的策略,它旨在避免不必要的资源消耗,直到这些资源真正被需要时才进行初始化。这个"17_懒汉式多线程...

    设计模式C++学习之单例模式(Singleton)

    但这种方式在多线程环境下可能存在问题,因为`instance`的初始化不是原子操作,可能导致多个线程同时创建对象。 为了解决这个问题,可以采用双重检查锁定(Double-Checked Locking)的策略: ```cpp class ...

    C++中实现Singleton的正确方法

    在本例中,`singleton2_t`的静态实例在`singleton1_t`之前被初始化,导致`singleton1_t`的`count_`在`singleton2_t`构造时被改变,从而产生了错误的结果。 正确的Singleton实现应考虑以下几点: 1. **线程安全**:...

    详解C++实现线程安全的单例模式

    总结来说,C++实现线程安全的单例模式通常涉及到对实例化过程的控制,以确保在多线程环境下只有一个实例存在。饿汉模式在类加载时完成实例化,是线程安全的,而懒汉模式需要额外的同步机制如互斥锁来保证线程安全。...

    C++CLI中实现singleton模式

    双重检测锁(Double-Checked Locking)实现的Singleton模式在多线程应用中有相当的价值。在ACE的实现中就大量使用ACE_Singleton模板类将普通类转换成具有Singleton行为的类。这种方式很好地消除了一些重复代码臭味,...

    Singleton模式源程序

    Singleton模式是一种设计模式,它是创建型模式的一种,用于控制类的实例化过程,确保一个类在整个应用程序中只有一个实例存在。这种模式在系统中需要频繁创建和...同时,这也是一次了解和实践C++多线程编程的好机会。

    Java的Singleton模式代码(免资源分)

    1. **非线程安全**:这个版本在多线程环境下存在安全隐患,多个线程可能会同时进入`if`语句块创建多个实例。 2. **懒加载**:实现了懒加载机制,但没有解决线程安全问题。 3. **简单性**:相对于双重检查锁定,该...

    singleton单例模式

    2. **双重检查锁定(Double-Checked Locking)**:这种方法是在多线程环境下保证线程安全的单例。首先检查是否已经实例化,如果未实例化,则同步锁定构造函数,确保只有一个线程可以进入,然后创建实例。这种方式...

    C++实现的单例模式代码

    2. 双重检查锁定(DCL,Double-Check Locking)法(多线程) DCL法在创建实例时引入了锁机制,确保了多线程环境下的线程安全。如下: ```cpp class Singleton { private: Singleton() {} ~Singleton() {} ...

    C++设计模式课件12_Singleton_单件模式.pdf

    1. **难以实现线程安全:** 在多线程环境下,如果没有正确处理同步问题,可能会导致多个实例被创建。 2. **违背单一职责原则:** 单例模式将对象的创建与对象的功能混为一谈,使得类承担了过多的职责。 3. **隐藏了...

    Head First 设计模式 (五) 单件模式(Singleton pattern) C++实现

    但这种方式在多线程环境下可能存在问题,因为多个线程可能会同时进入`getInstance`,从而创建多个实例。 ```cpp class Singleton { private: Singleton() {} Singleton(const Singleton&) = delete; Singleton...

Global site tag (gtag.js) - Google Analytics