MST

星途 面试题库

面试题:C++优化全局变量引用性能在多线程环境下的考量

在多线程C++程序中,存在一个全局变量`std::vector<int> globalVec`,多个线程会对其进行读操作。为了优化对`globalVec`的引用性能,并且保证线程安全,你会采取哪些措施?请详细说明涉及到的C++特性和实现思路。
31.2万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 使用std::shared_ptrstd::mutex
    • C++特性
      • std::shared_ptr:用于管理动态分配的对象(这里是std::vector<int>),它可以自动处理对象的内存释放,通过引用计数机制,当最后一个指向对象的shared_ptr被销毁时,对象的内存会被自动释放。
      • std::mutex:提供了一种互斥机制,用于保护共享资源(globalVec),确保同一时间只有一个线程可以访问该资源。
    • 实现思路
      • 声明一个std::shared_ptr<std::vector<int>>类型的全局变量,例如std::shared_ptr<std::vector<int>> globalVecPtr
      • 声明一个std::mutex对象,例如std::mutex globalVecMutex
      • 读操作时,首先锁定mutex,然后通过shared_ptr获取vector的引用进行读取,读取完成后解锁mutex。示例代码如下:
#include <iostream>
#include <vector>
#include <memory>
#include <mutex>
#include <thread>

std::shared_ptr<std::vector<int>> globalVecPtr = std::make_shared<std::vector<int>>();
std::mutex globalVecMutex;

void readVector() {
    std::lock_guard<std::mutex> lock(globalVecMutex);
    const auto& vec = *globalVecPtr;
    // 进行读操作,例如打印vector内容
    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}

int main() {
    // 初始化globalVecPtr
    globalVecPtr->push_back(1);
    globalVecPtr->push_back(2);

    std::thread t1(readVector);
    std::thread t2(readVector);

    t1.join();
    t2.join();

    return 0;
}
  1. 使用std::atomicstd::vector的拷贝
    • C++特性
      • std::atomic:提供原子操作,保证对其修饰的变量的操作是原子的,即不可分割的,不会被其他线程打断。
    • 实现思路
      • 声明一个std::atomic<std::vector<int>>类型的全局变量,例如std::atomic<std::vector<int>> globalVecAtomic
      • 读操作时,通过load方法获取vector的副本,然后对副本进行读操作。示例代码如下:
#include <iostream>
#include <vector>
#include <atomic>
#include <thread>

std::atomic<std::vector<int>> globalVecAtomic;

void readVector() {
    auto localVec = globalVecAtomic.load();
    // 进行读操作,例如打印vector内容
    for (int num : localVec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}

int main() {
    // 初始化globalVecAtomic
    std::vector<int> initVec = {1, 2};
    globalVecAtomic.store(initVec);

    std::thread t1(readVector);
    std::thread t2(readVector);

    t1.join();
    t2.join();

    return 0;
}
  1. 使用读写锁(std::shared_mutex
    • C++特性
      • std::shared_mutex:允许多个线程同时进行读操作,但只允许一个线程进行写操作。读操作可以并发执行,提高了读取性能。
    • 实现思路
      • 声明一个std::vector<int>类型的全局变量globalVec和一个std::shared_mutex对象,例如std::shared_mutex globalVecMutex
      • 读操作时,使用std::shared_lock<std::shared_mutex>来锁定mutex,这样可以允许多个线程同时进行读操作。示例代码如下:
#include <iostream>
#include <vector>
#include <shared_mutex>
#include <thread>

std::vector<int> globalVec;
std::shared_mutex globalVecMutex;

void readVector() {
    std::shared_lock<std::shared_mutex> lock(globalVecMutex);
    // 进行读操作,例如打印vector内容
    for (int num : globalVec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}

int main() {
    // 初始化globalVec
    globalVec.push_back(1);
    globalVec.push_back(2);

    std::thread t1(readVector);
    std::thread t2(readVector);

    t1.join();
    t2.join();

    return 0;
}