导读:本期聚焦于小伙伴创作的《C++中的mutex和lock是什么_C++多线程同步之互斥锁的使用》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++中的mutex和lock是什么_C++多线程同步之互斥锁的使用》有用,将其分享出去将是对创作者最好的鼓励。

在C++多线程开发中,当多个线程需要操作同一个共享变量或资源时,如果没有同步机制,就会出现数据不一致的问题。mutex(互斥锁)和lock(锁机制)就是用来解决这类线程同步问题的核心组件,二者配合可以保证共享资源在同一时间只被一个线程访问。

C++中的mutex和lock是什么_C++多线程同步之互斥锁的使用

mutex的基本概念

mutex是C++标准库提供的互斥量类型,定义在<mutex>头文件中,它的核心作用是实现线程间的互斥访问。当一个线程获取了mutex的所有权后,其他试图获取该mutex的线程会被阻塞,直到持有mutex的线程释放它。

C++标准库提供了多种mutex类型,常用的包括:

  • std::mutex:最基本的互斥锁,不支持递归获取,不支持定时等待
  • std::recursive_mutex:递归互斥锁,同一个线程可以多次获取该锁而不会死锁
  • std::timed_mutex:支持定时等待的互斥锁,线程可以尝试在指定时间内获取锁

lock的作用与使用方式

lock并不是单独的类型,而是指获取和释放互斥锁的操作过程,C++标准库提供了多种管理锁的方式,避免手动操作mutex时出现忘记释放锁的问题。

手动lock和unlock

std::mutex提供了lock()和unlock()两个成员函数,分别用于获取锁和释放锁,使用时必须保证获取锁之后一定要释放锁,否则会导致其他线程永久阻塞。

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

std::mutex g_mutex;
int g_counter = 0;

void increment_counter(int thread_id) {
    // 获取互斥锁
    g_mutex.lock();
    // 临界区:操作共享资源
    for (int i = 0; i < 1000; ++i) {
        ++g_counter;
    }
    std::cout << "线程" << thread_id << "完成计数,当前值:" << g_counter << std::endl;
    // 释放互斥锁
    g_mutex.unlock();
}

int main() {
    std::vector<std::thread> threads;
    for (int i = 0; i < 5; ++i) {
        threads.emplace_back(increment_counter, i);
    }
    for (auto& t : threads) {
        t.join();
    }
    std::cout << "最终计数结果:" << g_counter << std::endl;
    return 0;
}

使用std::lock_guard自动管理锁

手动调用lock和unlock容易遗漏unlock操作,尤其是在临界区抛出异常的场景下,因此更推荐使用RAII风格的锁管理类型,std::lock_guard就是最常用的一种。它会在构造时自动获取锁,析构时自动释放锁,即使临界区抛出异常也能保证锁被正确释放。

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

std::mutex g_mutex;
int g_counter = 0;

void increment_counter(int thread_id) {
    // 构造时自动获取锁
    std::lock_guard<std::mutex> lock(g_mutex);
    // 临界区:操作共享资源
    for (int i = 0; i < 1000; ++i) {
        ++g_counter;
    }
    std::cout << "线程" << thread_id << "完成计数,当前值:" << g_counter << std::endl;
    // 函数结束时lock对象析构,自动释放锁
}

int main() {
    std::vector<std::thread> threads;
    for (int i = 0; i < 5; ++i) {
        threads.emplace_back(increment_counter, i);
    }
    for (auto& t : threads) {
        t.join();
    }
    std::cout << "最终计数结果:" << g_counter << std::endl;
    return 0;
}

使用std::unique_lock更灵活管理锁

std::unique_lock比std::lock_guard更灵活,它支持延迟获取锁、手动释放锁、所有权转移等操作,适合需要更精细控制锁生命周期的场景。

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

std::mutex g_mutex;
int g_counter = 0;

void increment_counter(int thread_id) {
    // 延迟获取锁,先构造unique_lock再手动调用lock
    std::unique_lock<std::mutex> lock(g_mutex, std::defer_lock);
    // 执行一些不需要锁的操作
    std::cout << "线程" << thread_id << "准备获取锁" << std::endl;
    // 手动获取锁
    lock.lock();
    // 临界区操作
    for (int i = 0; i < 1000; ++i) {
        ++g_counter;
    }
    std::cout << "线程" << thread_id << "完成计数,当前值:" << g_counter << std::endl;
    // 可以手动提前释放锁
    lock.unlock();
    std::cout << "线程" << thread_id << "已释放锁" << std::endl;
}

int main() {
    std::vector<std::thread> threads;
    for (int i = 0; i < 5; ++i) {
        threads.emplace_back(increment_counter, i);
    }
    for (auto& t : threads) {
        t.join();
    }
    std::cout << "最终计数结果:" << g_counter << std::endl;
    return 0;
}

mutex和lock的使用注意事项

  • 不要重复对同一个std::mutex调用lock(),否则会导致未定义行为,递归场景应使用std::recursive_mutex
  • 尽量缩小临界区的范围,只把操作共享资源的代码放在锁的保护范围内,减少锁的持有时间
  • 避免多个线程按不同顺序获取多个锁,否则容易出现死锁问题,可以使用std::lock同时获取多个锁
  • 优先使用RAII风格的锁管理类型(lock_guard、unique_lock),避免手动调用lock和unlock

总结

mutex是C++中实现线程互斥的基础组件,而lock是获取和释放互斥锁的操作过程,二者配合可以有效解决多线程下的数据竞争问题。实际开发中推荐使用std::lock_guard或std::unique_lock来管理锁,既安全又便捷。合理设计锁的使用范围和获取顺序,能够写出更稳定高效的多线程程序。

mutexlock多线程同步互斥锁修改时间:2026-06-11 07:42:16

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。