MST

星途 面试题库

面试题:C++中std::move在多线程环境下的边界挑战与解决方案

在多线程环境下,当多个线程同时对一个对象使用std::move操作时,可能会遇到哪些边界问题?例如资源竞争、数据不一致等。请提出至少两种有效的解决方案,并通过编写多线程代码示例(使用C++标准库中的线程相关工具,如std::thread、std::mutex等)来详细阐述如何解决这些边界问题。
17.7万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

可能遇到的边界问题

  1. 资源竞争:多个线程同时std::move一个对象,可能导致对象资源(如动态分配的内存)被多次释放或访问已释放资源。
  2. 数据不一致std::move操作可能改变对象状态,如果多个线程同时操作,对象状态可能处于不一致状态,后续使用时会产生未定义行为。

解决方案及代码示例

  1. 使用互斥锁(std::mutex
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>

class Resource {
public:
    Resource() : data(new int(42)) {}
    ~Resource() { delete data; }
    Resource(const Resource&) = delete;
    Resource& operator=(const Resource&) = delete;
    Resource(Resource&& other) noexcept : data(other.data) {
        other.data = nullptr;
    }
    Resource& operator=(Resource&& other) noexcept {
        if (this != &other) {
            delete data;
            data = other.data;
            other.data = nullptr;
        }
        return *this;
    }
    int getData() const { return *data; }
private:
    int* data;
};

std::mutex resourceMutex;
Resource globalResource;

void moveResource() {
    std::lock_guard<std::mutex> lock(resourceMutex);
    Resource movedResource = std::move(globalResource);
    std::cout << "Thread moved resource with data: " << movedResource.getData() << std::endl;
}

int main() {
    std::vector<std::thread> threads;
    for (int i = 0; i < 5; ++i) {
        threads.emplace_back(moveResource);
    }
    for (auto& thread : threads) {
        thread.join();
    }
    return 0;
}
  1. 使用原子操作(std::atomic)结合智能指针(std::unique_ptr
#include <iostream>
#include <thread>
#include <atomic>
#include <memory>
#include <vector>

class Resource {
public:
    Resource() : data(42) {}
    int getData() const { return data; }
private:
    int data;
};

std::atomic<std::unique_ptr<Resource>> globalResource;

void moveResource() {
    std::unique_ptr<Resource> movedResource = globalResource.exchange(nullptr);
    if (movedResource) {
        std::cout << "Thread moved resource with data: " << movedResource->getData() << std::endl;
    }
}

int main() {
    globalResource.store(std::make_unique<Resource>());
    std::vector<std::thread> threads;
    for (int i = 0; i < 5; ++i) {
        threads.emplace_back(moveResource);
    }
    for (auto& thread : threads) {
        thread.join();
    }
    return 0;
}