MST

星途 面试题库

面试题:C++全局变量引用方式对多线程编程的影响

在多线程环境下,使用静态和动态方式引用全局变量分别会带来哪些问题?如何解决这些问题?请结合线程安全、数据竞争等概念进行阐述,并给出相关代码片段说明。
25.9万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

静态方式引用全局变量

  1. 问题
    • 线程安全问题:静态引用全局变量时,由于多个线程共享全局变量,若多个线程同时对其进行读写操作,会导致数据竞争。例如,一个线程读取全局变量的值并进行修改,在修改完成前,另一个线程也读取了该值,那么最终结果可能不是预期的。
    • 数据竞争:当多个线程同时访问和修改全局变量时,会产生数据竞争。这会导致程序出现不确定的行为,例如计算结果错误、程序崩溃等。
  2. 解决方法
    • 使用互斥锁(Mutex):通过互斥锁来保护对全局变量的访问。在访问全局变量前,线程必须先获取互斥锁,访问完成后释放互斥锁。这样可以确保同一时间只有一个线程能访问全局变量,避免数据竞争。
    • 读写锁(Read - Write Lock):如果对全局变量的读操作远多于写操作,可以使用读写锁。多个线程可以同时进行读操作,但写操作时需要独占锁,这样可以提高并发性能。

代码示例(以C++为例,使用互斥锁)

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

std::mutex globalMutex;
int globalVariable = 0;

void increment() {
    for (int i = 0; i < 10000; ++i) {
        globalMutex.lock();
        globalVariable++;
        globalMutex.unlock();
    }
}

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

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

    std::cout << "Final value of global variable: " << globalVariable << std::endl;
    return 0;
}

动态方式引用全局变量

  1. 问题
    • 线程安全和数据竞争问题与静态类似:动态引用全局变量时,同样存在多个线程共享该变量的情况,若没有适当的同步机制,会出现线程安全问题和数据竞争。例如,动态分配的全局变量可能被多个线程同时访问和修改,导致不一致的状态。
    • 内存管理问题:动态分配的全局变量在多线程环境下的内存释放需要特别小心。如果一个线程释放了内存,而其他线程还持有指向该内存的指针,就会导致悬空指针问题,进而引发程序崩溃。
  2. 解决方法
    • 同步机制:与静态引用一样,可以使用互斥锁、读写锁等同步机制来保护对动态分配全局变量的访问。
    • 智能指针:使用智能指针(如std::shared_ptr)来管理动态分配的全局变量。std::shared_ptr通过引用计数来自动管理内存释放,减少了手动释放内存带来的风险。

代码示例(以C++为例,使用互斥锁和智能指针)

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

std::mutex globalMutex;
std::shared_ptr<int> globalDynamicVariable = std::make_shared<int>(0);

void increment() {
    for (int i = 0; i < 10000; ++i) {
        globalMutex.lock();
        (*globalDynamicVariable)++;
        globalMutex.unlock();
    }
}

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

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

    std::cout << "Final value of global dynamic variable: " << *globalDynamicVariable << std::endl;
    return 0;
}