MST

星途 面试题库

面试题:C++常对象在多线程并发访问时的同步机制

假设有一个C++常对象,多个线程会并发访问它的某个常成员函数,该函数会读取一些共享数据。请详细阐述如何设计同步机制以确保数据的一致性,同时尽量减少锁带来的性能开销,并举例说明使用哪些C++标准库中的工具来实现。
42.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

1. 同步机制设计思路

  • 读 - 写锁(Read - Write Lock):因为是多个线程并发读共享数据,只有读操作时不会产生数据不一致问题,所以可以使用读 - 写锁。读 - 写锁允许多个线程同时进行读操作,但只允许一个线程进行写操作,这样在保证数据一致性的同时,能减少锁带来的性能开销。

2. C++标准库工具实现

  • C++17引入的std::shared_mutex:这是一个读 - 写锁类型。
  • 示例代码
#include <iostream>
#include <thread>
#include <mutex>
#include <shared_mutex>

class SharedData {
public:
    int data;
    std::shared_mutex mtx;
};

class MyClass {
public:
    const SharedData& sharedData;
    MyClass(const SharedData& data) : sharedData(data) {}
    // 常成员函数
    void readData() const {
        std::shared_lock<std::shared_mutex> lock(sharedData.mtx);
        std::cout << "Reading data: " << sharedData.data << std::endl;
    }
};

void threadFunction(const MyClass& obj) {
    obj.readData();
}

int main() {
    SharedData sharedData;
    sharedData.data = 42;
    MyClass obj(sharedData);

    std::thread threads[5];
    for (int i = 0; i < 5; i++) {
        threads[i] = std::thread(threadFunction, std::ref(obj));
    }

    for (auto& thread : threads) {
        thread.join();
    }

    return 0;
}

在上述代码中:

  • SharedData类包含共享数据data和一个std::shared_mutex实例mtx
  • MyClass的常成员函数readData使用std::shared_lock来获取读锁,允许多个线程同时读。
  • main函数中,创建多个线程并发调用readData函数,展示了读 - 写锁的使用方式。通过这种方式,在多个线程并发读取共享数据时,既保证了数据一致性,又减少了锁的性能开销。