MST

星途 面试题库

面试题:C++多线程编程中互斥锁的使用场景及实现原理

请阐述在C++多线程编程里,互斥锁(mutex)一般用于哪些场景?并简要说明其实现线程同步的原理。另外,使用C++标准库中的std::mutex,编写一段简单代码,实现两个线程交替打印数字1 - 10。
34.1万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

互斥锁(mutex)适用场景

  1. 共享资源访问:当多个线程需要访问共享资源(如共享内存、文件、数据库连接等)时,为防止数据竞争,使用互斥锁确保同一时间只有一个线程能访问该资源。
  2. 临界区保护:保护代码中的临界区,临界区是指访问共享资源的那段代码,互斥锁可以保证每次只有一个线程进入临界区执行代码。

线程同步原理

互斥锁有一个内部状态,用于表示锁的占用情况。在初始状态下,锁是未被占用的。当一个线程尝试获取(lock)互斥锁时,如果锁未被占用,该线程会成功获取锁并将其状态设为已占用,此时该线程可以进入临界区访问共享资源。当线程访问完共享资源后,会释放(unlock)互斥锁,将其状态重新设为未占用,以便其他线程可以获取锁进入临界区。如果一个线程尝试获取已被占用的互斥锁,该线程会被阻塞,直到持有锁的线程释放锁,这样就保证了同一时间只有一个线程能进入临界区,实现了线程同步。

代码实现

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

std::mutex mtx;
int num = 1;

void print_numbers(int id) {
    while (num <= 10) {
        mtx.lock();
        if (num <= 10) {
            std::cout << "Thread " << id << " prints " << num << std::endl;
            num++;
        }
        mtx.unlock();
    }
}

int main() {
    std::thread t1(print_numbers, 1);
    std::thread t2(print_numbers, 2);

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

    return 0;
}

在这段代码中,定义了一个std::mutex对象mtx用于保护共享变量num。两个线程t1t2在函数print_numbers中尝试获取互斥锁mtx,获取成功后打印当前num的值并递增num,然后释放互斥锁,从而实现两个线程交替打印数字1 - 10。