MST

星途 面试题库

面试题:C++静态函数在多线程环境下的资源竞争与处理

考虑一个场景,有一个C++程序,包含一个静态函数 `loadConfig`,它负责从文件中加载配置信息并存储在静态成员变量中,如下代码: ```cpp class Config { public: static void loadConfig(const std::string& filePath) { std::ifstream file(filePath); std::string line; if (file.is_open()) { while (std::getline(file, line)) { // 解析配置信息并设置到静态成员变量中 // 假设这里有个静态成员变量configData configData += line; } file.close(); } } static std::string configData; }; std::string Config::configData = ""; ``` 如果多个线程同时调用 `loadConfig` 函数,会产生什么线程安全问题?请给出至少两种不同的解决方案,并分析每种方案的优缺点。
16.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

线程安全问题

多个线程同时调用 loadConfig 函数时,会产生数据竞争问题。因为多个线程同时对静态成员变量 configData 进行写入操作,可能导致 configData 的内容出现不一致或损坏。

解决方案一:互斥锁(Mutex)

  1. 实现代码
#include <iostream>
#include <fstream>
#include <string>
#include <mutex>

class Config {
public:
    static void loadConfig(const std::string& filePath) {
        std::lock_guard<std::mutex> lock(mutex_);
        std::ifstream file(filePath);
        std::string line;
        if (file.is_open()) {
            while (std::getline(file, line)) {
                configData += line;
            }
            file.close();
        }
    }
    static std::string configData;
private:
    static std::mutex mutex_;
};
std::string Config::configData = "";
std::mutex Config::mutex_;
  1. 优点
    • 实现简单,能够有效避免数据竞争问题。
    • 对现有代码侵入性较小,只需要在关键代码段添加锁操作。
  2. 缺点
    • 性能开销较大,因为同一时间只有一个线程能进入临界区,其他线程需要等待,可能导致线程阻塞,降低程序整体性能。
    • 可能产生死锁,如果多个线程以不同顺序获取多个锁,可能会导致死锁情况。

解决方案二:读写锁(Read - Write Lock)

  1. 实现代码
#include <iostream>
#include <fstream>
#include <string>
#include <shared_mutex>

class Config {
public:
    static void loadConfig(const std::string& filePath) {
        std::unique_lock<std::shared_mutex> lock(mutex_);
        std::ifstream file(filePath);
        std::string line;
        if (file.is_open()) {
            while (std::getline(file, line)) {
                configData += line;
            }
            file.close();
        }
    }
    static std::string configData;
private:
    static std::shared_mutex mutex_;
};
std::string Config::configData = "";
std::shared_mutex Config::mutex_;
  1. 优点
    • 读操作可以并发执行,在配置信息加载完成后,如果有较多读操作,读写锁能提高程序性能。
    • 对于写操作,仍然能保证线程安全,避免数据竞争。
  2. 缺点
    • 实现相对复杂,需要根据实际读写操作的比例和频率来合理使用。
    • 仍然可能产生死锁,例如多个线程在不同条件下获取读锁和写锁,可能导致死锁。