MST

星途 面试题库

面试题:C++中static成员函数在多线程环境下的特性与应用

在多线程编程中,C++的static成员函数会面临哪些特殊问题?比如资源竞争等情况。如何利用static成员函数实现线程安全的单例模式?请写出关键代码并解释原理。
24.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

1. C++ 的 static 成员函数在多线程编程中面临的特殊问题

  • 资源竞争:虽然 static 成员函数本身没有 this 指针,不直接操作类的实例成员,但它可能会访问和修改 static 成员变量。如果多个线程同时调用 static 成员函数并对 static 成员变量进行读写操作,就会导致资源竞争问题,可能出现数据不一致等错误。
  • 初始化顺序:如果 static 成员函数依赖于其他 static 变量的初始化,在多线程环境下,不同线程可能以不同顺序初始化相关 static 变量,导致未定义行为。

2. 利用 static 成员函数实现线程安全的单例模式

以下是 C++11 及之后版本利用 static 成员函数实现线程安全单例模式的关键代码:

class Singleton {
private:
    // 私有构造函数,防止外部实例化
    Singleton() = default;
    // 禁止拷贝构造和赋值运算符
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;

public:
    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }
};

原理解释

  • 静态局部变量getInstance 函数中的 static Singleton instance; 定义了一个静态局部变量。在 C++11 标准之后,这种静态局部变量的初始化是线程安全的。当第一个线程调用 getInstance 时,instance 会被初始化,后续线程调用时直接返回已初始化的实例。
  • 私有构造函数:类的构造函数是私有的,这就防止了在类外部通过 new 或其他方式创建多个实例。
  • 禁止拷贝和赋值:通过 delete 关键字禁用拷贝构造函数和赋值运算符,确保单例的唯一性,避免在传递对象或赋值时创建新的实例。