MST

星途 面试题库

面试题:C++ 线程同步机制不当引发崩溃的分析与修复

假设在一个多线程 C++ 程序中,由于线程同步机制使用不当,频繁出现线程崩溃现象。给定一段存在此类问题的示例代码(可自行假设代码结构,包含多个线程对共享资源的操作),请分析可能导致崩溃的原因,并给出正确的修复方案。
31.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

假设示例代码

#include <iostream>
#include <thread>
#include <mutex>

int sharedResource = 0;
std::mutex resourceMutex;

void increment() {
    for (int i = 0; i < 1000; ++i) {
        // 这里缺少对共享资源访问的保护
        sharedResource++;
    }
}

void decrement() {
    for (int i = 0; i < 1000; ++i) {
        // 这里缺少对共享资源访问的保护
        sharedResource--;
    }
}
int main() {
    std::thread thread1(increment);
    std::thread thread2(decrement);

    thread1.join();
    thread2.join();

    std::cout << "Final value of sharedResource: " << sharedResource << std::endl;
    return 0;
}

可能导致崩溃的原因

  1. 竞态条件(Race Condition):多个线程同时访问和修改 sharedResource 这个共享资源,而没有适当的同步机制。这会导致数据竞争,使得 sharedResource 的值可能被错误地修改,进而可能导致程序崩溃。例如,一个线程读取 sharedResource 的值,另一个线程同时修改了该值,第一个线程基于旧值进行的后续操作就可能产生错误。

正确的修复方案

  1. 使用互斥锁(Mutex):在访问共享资源前锁定互斥锁,访问完成后解锁互斥锁。修改后的代码如下:
#include <iostream>
#include <thread>
#include <mutex>

int sharedResource = 0;
std::mutex resourceMutex;

void increment() {
    for (int i = 0; i < 1000; ++i) {
        std::lock_guard<std::mutex> lock(resourceMutex);
        sharedResource++;
    }
}

void decrement() {
    for (int i = 0; i < 1000; ++i) {
        std::lock_guard<std::mutex> lock(resourceMutex);
        sharedResource--;
    }
}
int main() {
    std::thread thread1(increment);
    std::thread thread2(decrement);

    thread1.join();
    thread2.join();

    std::cout << "Final value of sharedResource: " << sharedResource << std::endl;
    return 0;
}

std::lock_guard 是一个 RAII(Resource Acquisition Is Initialization) 类,在构造时自动锁定互斥锁,在析构时自动解锁互斥锁,确保了在访问共享资源时的线程安全。

  1. 使用其他同步机制:除了互斥锁,还可以使用 std::unique_lock 来获得更灵活的锁控制,或者使用 std::condition_variable 来实现线程间的条件同步,不过对于这个简单的示例,std::lock_guard 配合 std::mutex 已经足够。