面试题答案
一键面试-
异常处理策略:
- 在每个线程的入口函数中设置一个try - catch块。例如,如果线程执行的函数是
void threadFunction()
,则在启动线程的代码中可以这样写:
std::thread t([&] { try { threadFunction(); } catch (const std::exception& e) { // 记录异常信息,比如使用日志库 std::cerr << "Thread caught exception: " << e.what() << std::endl; // 这里可以进行一些清理操作,比如释放该线程持有的资源 } });
- 这样,即使
threadFunction
抛出异常,也不会导致整个进程崩溃,异常会在catch块中被捕获并处理。
- 在每个线程的入口函数中设置一个try - catch块。例如,如果线程执行的函数是
-
线程同步机制与数据一致性:
- Mutex(互斥锁):
- 用于保护共享资源。例如,当多个线程可能访问和修改同一个数据结构(如共享的
std::vector<int>
)时,在访问和修改前需要加锁。
std::mutex mtx; std::vector<int> sharedVector; void modifySharedVector(int value) { std::lock_guard<std::mutex> lock(mtx); sharedVector.push_back(value); }
- 在上述代码中,
std::lock_guard
在构造时自动加锁,在析构时自动解锁,保证了在修改sharedVector
时不会被其他线程干扰,维持数据一致性。
- 用于保护共享资源。例如,当多个线程可能访问和修改同一个数据结构(如共享的
- Condition Variable(条件变量):
- 通常与Mutex一起使用,用于线程间的同步。比如,有一个线程负责生产数据到共享队列,另一个线程负责从共享队列消费数据。
std::mutex mtx; std::condition_variable cv; std::queue<int> sharedQueue; bool dataReady = false; // 生产者线程 void producer() { int data = 42; { std::unique_lock<std::mutex> lock(mtx); sharedQueue.push(data); dataReady = true; } cv.notify_one(); } // 消费者线程 void consumer() { std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, [] { return dataReady; }); int value = sharedQueue.front(); sharedQueue.pop(); dataReady = false; }
- 在生产者线程中,当数据放入共享队列后,通过
cv.notify_one()
通知等待的消费者线程。消费者线程通过cv.wait(lock, [] { return dataReady; });
等待数据准备好的条件,这样可以避免无效的等待,同时利用Mutex保护共享队列,维持数据一致性。
- Mutex(互斥锁):