MST

星途 面试题库

面试题:C++中全局变量在多线程环境下可能出现的弊端及解决方法

在C++多线程编程中,使用全局变量可能会引发哪些问题?请举例说明,并阐述至少一种解决这些问题的方法。
38.2万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

可能引发的问题

  1. 数据竞争(Data Race):多个线程同时访问和修改全局变量,导致结果不可预测。例如:
#include <iostream>
#include <thread>

int globalVar = 0;

void increment() {
    for (int i = 0; i < 10000; ++i) {
        globalVar++;
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);

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

    std::cout << "Expected: 20000, Actual: " << globalVar << std::endl;
    return 0;
}

在上述代码中,两个线程同时对 globalVar 进行自增操作,由于自增操作不是原子的,可能会出现数据竞争,导致最终 globalVar 的值不一定是 20000。

  1. 线程安全问题:全局变量在不同线程间共享,可能被意外修改,破坏程序的逻辑。比如一个线程依赖全局变量的初始状态进行计算,但另一个线程在其计算过程中修改了该全局变量。

解决方法

  1. 使用互斥锁(Mutex)
#include <iostream>
#include <thread>
#include <mutex>

std::mutex globalMutex;
int globalVar = 0;

void increment() {
    for (int i = 0; i < 10000; ++i) {
        std::lock_guard<std::mutex> lock(globalMutex);
        globalVar++;
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);

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

    std::cout << "Expected: 20000, Actual: " << globalVar << std::endl;
    return 0;
}

这里通过 std::mutexstd::lock_guard 来保护对 globalVar 的访问,确保同一时间只有一个线程能修改 globalVar,从而避免数据竞争。

  1. 使用原子变量(Atomic Variables):C++11 引入了原子类型,对原子类型的操作是原子的,不会产生数据竞争。例如:
#include <iostream>
#include <thread>
#include <atomic>

std::atomic<int> globalVar(0);

void increment() {
    for (int i = 0; i < 10000; ++i) {
        globalVar++;
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);

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

    std::cout << "Expected: 20000, Actual: " << globalVar << std::endl;
    return 0;
}

std::atomic<int> 类型的 globalVar 保证了自增操作的原子性,避免了数据竞争问题。