MST
星途 面试题库

面试题:C++多线程复杂场景下的互斥策略优化

在一个C++多线程的大型项目中,有多个线程频繁访问和修改一组共享资源(包括多个不同类型的变量和数据结构),并且对性能要求极高。现有的互斥锁策略导致了明显的性能瓶颈。请阐述如何优化互斥策略,在保证数据一致性的前提下提高系统性能,说明优化思路并给出关键代码示例。
15.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

优化思路

  1. 细粒度锁:将共享资源按访问频率或功能拆分成多个子部分,为每个子部分分配单独的锁。这样不同线程在访问不同子部分时不会相互阻塞。
  2. 读写锁:如果共享资源的读操作远多于写操作,可以使用读写锁。读操作时允许多个线程同时进行,写操作时则独占资源,防止其他读写操作。
  3. 无锁数据结构:对于某些数据结构,如栈、队列等,可以使用无锁数据结构来避免锁带来的开销。这些数据结构通常使用原子操作实现。
  4. 锁粗化:如果在一段代码中频繁获取和释放同一把锁,可以将锁的作用范围扩大,减少锁的获取和释放次数。

关键代码示例

  1. 细粒度锁示例
#include <mutex>
#include <thread>
#include <vector>

std::mutex mutex1, mutex2;
int data1 = 0;
std::vector<int> data2;

void threadFunction1() {
    for (int i = 0; i < 1000000; ++i) {
        std::lock_guard<std::mutex> lock(mutex1);
        data1++;
    }
}

void threadFunction2() {
    for (int i = 0; i < 1000000; ++i) {
        std::lock_guard<std::mutex> lock(mutex2);
        data2.push_back(i);
    }
}
  1. 读写锁示例
#include <shared_mutex>
#include <thread>
#include <iostream>

std::shared_mutex rwMutex;
int sharedData = 0;

void readFunction() {
    std::shared_lock<std::shared_mutex> lock(rwMutex);
    std::cout << "Read data: " << sharedData << std::endl;
}

void writeFunction() {
    std::unique_lock<std::shared_mutex> lock(rwMutex);
    sharedData++;
    std::cout << "Write data: " << sharedData << std::endl;
}
  1. 无锁数据结构示例(以无锁栈为例)
#include <atomic>
#include <memory>

template<typename T>
class LockFreeStack {
private:
    struct Node {
        T data;
        std::unique_ptr<Node> next;
        Node(const T& value) : data(value) {}
    };

    std::atomic<Node*> head;

public:
    LockFreeStack() : head(nullptr) {}

    void push(const T& value) {
        auto newNode = std::make_unique<Node>(value);
        Node* oldHead = head.load();
        do {
            newNode->next = std::move(oldHead);
        } while (!head.compare_exchange_weak(oldHead, newNode.release()));
    }

    bool pop(T& value) {
        Node* oldHead = head.load();
        do {
            if (!oldHead) return false;
            Node* newHead = oldHead->next.get();
        } while (!head.compare_exchange_weak(oldHead, newHead));
        value = std::move(oldHead->data);
        return true;
    }
};
  1. 锁粗化示例
#include <mutex>
#include <thread>
#include <vector>

std::mutex globalMutex;
std::vector<int> globalData;

void oldThreadFunction() {
    for (int i = 0; i < 1000000; ++i) {
        std::lock_guard<std::mutex> lock(globalMutex);
        globalData.push_back(i);
    }
}

void newThreadFunction() {
    std::lock_guard<std::mutex> lock(globalMutex);
    for (int i = 0; i < 1000000; ++i) {
        globalData.push_back(i);
    }
}