面试题答案
一键面试可能出现的问题
多个线程同时对共享的 std::string
使用 append
函数可能会导致数据竞争问题。由于 append
操作不是原子的,在多线程环境下,可能会出现一个线程正在修改字符串内部结构(如重新分配内存、复制字符等)时,另一个线程也开始进行相同操作,最终导致程序出现未定义行为,如数据损坏、程序崩溃等。
线程安全机制设计
- 使用
std::mutex
:std::mutex
是 C++ 标准库提供的互斥锁,用于保护共享资源。在对共享字符串进行操作前,先锁定互斥锁,操作完成后再解锁,这样可以保证同一时间只有一个线程能访问共享字符串。 - 使用
std::condition_variable
(可选):std::condition_variable
通常与std::mutex
一起使用,用于线程间的同步。当某个条件满足时,它可以通知等待的线程。在字符串操作场景中,如果有一些复杂的条件,比如字符串长度达到某个值时通知其他线程进行处理,就可以使用std::condition_variable
。
代码示例
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
std::string sharedStr;
void appendString(const std::string& strToAppend) {
std::unique_lock<std::mutex> lock(mtx);
sharedStr.append(strToAppend);
lock.unlock();
cv.notify_all(); // 如果有需要,通知其他线程
}
void printString() {
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [] { return!sharedStr.empty(); }); // 等待字符串有内容
std::cout << "Printing string: " << sharedStr << std::endl;
}
int main() {
std::thread t1(appendString, "Hello");
std::thread t2(appendString, " World!");
std::thread t3(printString);
t1.join();
t2.join();
t3.join();
return 0;
}
在上述代码中:
appendString
函数使用std::mutex
来保护对sharedStr
的append
操作。printString
函数使用std::condition_variable
等待sharedStr
不为空,然后打印字符串。这样可以确保在字符串有内容时才进行打印操作。