MST
星途 面试题库

面试题:C++ 多线程中复杂场景下互斥与同步的应用

假设有一个C++程序,多个线程需要访问并修改共享的复杂数据结构(如自定义的图结构)。请设计一套合理的互斥与同步方案,确保数据的一致性和线程安全,同时要考虑性能问题。描述你选择的具体同步机制(如互斥锁、条件变量、信号量等)及其原因,并简单说明实现思路。
24.3万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 选择的同步机制
    • 互斥锁(std::mutex:用于保护共享数据结构的临界区,确保同一时间只有一个线程可以访问和修改共享的图结构。原因是它简单直接,能有效防止多个线程同时访问共享资源,避免数据竞争。
    • 条件变量(std::condition_variable:当某个线程需要等待共享数据结构满足特定条件时使用,比如等待图结构中某个节点被其他线程处理完成。它与互斥锁配合使用,能减少线程的无效等待,提高性能。
  2. 实现思路
    • 使用互斥锁
      • 定义一个全局的std::mutex对象,例如std::mutex graphMutex;
      • 在每个需要访问和修改共享图结构的函数中,使用std::lock_guard<std::mutex>来自动管理锁的生命周期。例如:
void modifyGraph() {
    std::lock_guard<std::mutex> lock(graphMutex);
    // 这里进行对共享图结构的修改操作
}
  • 使用条件变量
    • 定义一个全局的std::condition_variable对象,例如std::condition_variable graphCondition;
    • 当一个线程需要等待某个条件时,先获取互斥锁,然后使用std::unique_lock<std::mutex>与条件变量配合。例如,假设共享图结构中有一个成员变量bool nodeProcessed表示某个节点是否处理完成:
void waitForNode() {
    std::unique_lock<std::mutex> lock(graphMutex);
    graphCondition.wait(lock, [] { return nodeProcessed; });
    // 当条件满足,即节点处理完成后,继续执行相关操作
}
  • 在修改共享图结构并满足某个条件时,通知等待的线程
void processNode() {
    std::lock_guard<std::mutex> lock(graphMutex);
    // 处理节点
    nodeProcessed = true;
    graphCondition.notify_one();// 通知一个等待的线程
    // 或者 graphCondition.notify_all();通知所有等待的线程
}

这样通过互斥锁保证数据访问的互斥性,通过条件变量实现线程间的同步,在保证数据一致性和线程安全的同时,尽可能提高性能。