MST

星途 面试题库

面试题:C++多线程环境下异常安全与进程稳定性

假设在一个C++多线程程序中,某个线程执行的函数可能抛出异常,描述如何通过恰当的异常处理策略和线程同步机制,保证即使该线程因异常崩溃,整个进程仍能正常运行,并且其他线程不受影响。同时说明在这种情况下常用的线程同步原语(如mutex、condition variable等)如何正确使用以维持数据一致性。
35.9万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 异常处理策略

    • 在每个线程的入口函数中设置一个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块中被捕获并处理。
  2. 线程同步机制与数据一致性

    • 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保护共享队列,维持数据一致性。