面试题答案
一键面试线程安全问题
多个线程同时调用 loadConfig
函数时,会产生数据竞争问题。因为多个线程同时对静态成员变量 configData
进行写入操作,可能导致 configData
的内容出现不一致或损坏。
解决方案一:互斥锁(Mutex)
- 实现代码
#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_;
- 优点
- 实现简单,能够有效避免数据竞争问题。
- 对现有代码侵入性较小,只需要在关键代码段添加锁操作。
- 缺点
- 性能开销较大,因为同一时间只有一个线程能进入临界区,其他线程需要等待,可能导致线程阻塞,降低程序整体性能。
- 可能产生死锁,如果多个线程以不同顺序获取多个锁,可能会导致死锁情况。
解决方案二:读写锁(Read - Write Lock)
- 实现代码
#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_;
- 优点
- 读操作可以并发执行,在配置信息加载完成后,如果有较多读操作,读写锁能提高程序性能。
- 对于写操作,仍然能保证线程安全,避免数据竞争。
- 缺点
- 实现相对复杂,需要根据实际读写操作的比例和频率来合理使用。
- 仍然可能产生死锁,例如多个线程在不同条件下获取读锁和写锁,可能导致死锁。