21xrx.com
2024-09-19 10:14:38 Thursday
登录
文章检索 我的文章 写文章
C++11实现线程安全的单例模式
2023-07-05 03:10:09 深夜i     --     --
C++11 线程安全 单例模式

单例模式是一种非常常见的设计模式,它能够确保一个类只有一个实例,并且提供全局访问。但是,在多线程环境下,单例模式可能出现线程安全问题。因此,需要对单例模式进行线程安全处理。C++11提供了一种方便的方法来实现线程安全的单例模式。

首先,我们来看一下单例模式的实现。通常情况下,我们使用静态变量来存储实例,并在需要的时候进行初始化。但是,这种实现方式对于多线程环境来说并不是线程安全的。如果多个线程同时调用getInstance()方法,就有可能创建多个实例。

因此,我们需要对getInstance()方法进行加锁,在同一时刻只能有一个线程获得实例。但是,传统的加锁方式可能会降低程序的性能,因为它需要不断地检查锁状态。C++11提供了一种更高效的加锁方式,即std::once_flag。

使用std::once_flag可以确保一个函数只会被执行一次。具体实现方式如下:


class Singleton {

public:

  static Singleton& getInstance()

    static Singleton instance;

    return instance;

  

private:

  Singleton() {}

  Singleton(const Singleton&);

  Singleton& operator=(const Singleton&);

};

// 使用std::once_flag确保getInstance()只会被执行一次

class ThreadSafeSingleton {

public:

  static ThreadSafeSingleton& getInstance()

    static ThreadSafeSingleton instance;

    return instance;

  

private:

  ThreadSafeSingleton() {}

  ThreadSafeSingleton(const ThreadSafeSingleton&);

  ThreadSafeSingleton& operator=(const ThreadSafeSingleton&);

};

class ThreadSafeSingleton {

public:

  static ThreadSafeSingleton& getInstance() {

    static std::once_flag flag;

    static ThreadSafeSingleton* instance = nullptr;

    // 使用std::call_once确保getInstance()只会被执行一次

    std::call_once(flag, []() {

      instance = new ThreadSafeSingleton();

    });

    return *instance;

  }

private:

  ThreadSafeSingleton() {}

  ThreadSafeSingleton(const ThreadSafeSingleton&);

  ThreadSafeSingleton& operator=(const ThreadSafeSingleton&);

};

可以看到,在ThreadSafeSingleton::getInstance()中,我们使用了std::once_flag来确保getInstance()只会被执行一次。我们创建了一个静态的std::once_flag对象flag和一个ThreadSafeSingleton对象指针instance,并在lambda表达式中对instance进行了初始化。

当多个线程调用getInstance()方法时,只有一个线程能够进入lambda表达式对instance进行初始化。其他线程会被阻塞,直到初始化完成后才能继续执行。

总的来说,使用std::once_flag可以很方便地实现线程安全的单例模式。与传统的加锁方式相比,它可以提高程序的性能,并且不容易出现死锁等问题。因此,在C++11中,建议使用std::once_flag来实现线程安全的单例模式。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复