82人参与 • 2026-05-11 • C/C++
optimized tool selectionc++ 标准库中有多种锁管理机制,各有不同的特性和适用场景:
看这段代码中使用的是 std::lock_guard,这是一个自动管理锁的工具。锁会在以下时刻释放:
.....
static std::mutex g_mutex; // 保护 g_control / g_reply 的并发访问
.....
void handlecontrolgram(const controlgram &cg) {
std::lock_guard<std::mutex> lk(g_mutex); // ← 获取锁
g_control.steeringthrottle = (uint8_t)cg.steeringthrottle;
// ... 其他赋值操作
g_control.controlmode = cg.controlmode;
} // ← 函数结束时,lk 对象析构,锁自动释放
锁的释放时机:
lock_guard 对象超出作用域,析构函数被调用,锁自动释放unlock()这是 raii 模式(resource acquisition is initialization)的应用:
| 情形 | 手动 lock/unlock | lock_guard |
|---|---|---|
| 正常执行 | ✓ 释放 | ✓ 自动释放 |
| 异常抛出 | ✗ 锁泄露 | ✓ 析构仍会释放 |
| 逻辑分支 | ✗ 容易遗漏 | ✓ 自动保证 |
在 c++ 中,锁是解决多线程数据竞争的核心工具(c++11 及以后标准提供了完善的锁机制)。针对你的 nvidia orin(ubuntu20.04,arm 架构),所有标准 c++ 锁都可以直接使用,编译时仅需链接线程库(-pthread)。
我会分 底层互斥体(锁本体)、raii 自动锁管理工具(推荐必用) 两部分讲解,包含种类、特性、区别、使用场景、代码示例,最后给避坑指南。
#include <mutex> // c++11 基础锁 #include <shared_mutex> // c++17 读写锁 #include <thread> // 线程
lock()/unlock()(极易忘记解锁导致死锁)。g++ -std=c++17 代码.cpp -o 程序 -pthread
这是锁的核心实现,分为 独占锁、递归锁、超时锁、读写锁 4 大类,共 5 种:
| 互斥体类型 | 独占性 | 递归 | 超时 | 共享读写 | c++ 版本 | 核心特性 |
|---|---|---|---|---|---|---|
std::mutex | ✅ 独占 | ❌ | ❌ | ❌ | c++11 | 最基础、性能最高 |
std::recursive_mutex | ✅ 独占 | ✅ | ❌ | ❌ | c++11 | 同一线程可重复加锁 |
std::timed_mutex | ✅ 独占 | ❌ | ✅ | ❌ | c++11 | 可尝试加锁,超时放弃 |
std::recursive_timed_mutex | ✅ 独占 | ✅ | ✅ | ❌ | c++11 | 递归+超时 |
std::shared_mutex | ✅ 独占 | ❌ | ❌ | ✅ 读写分离 | c++17 | 读共享、写独占 |
mutex。try_lock_for(时间)、try_lock_until(时间点)。直接操作底层互斥体容易忘记解锁,c++ 提供了 4 种自动锁工具,构造时加锁,析构时自动解锁:
| 管理工具 | 配合锁类型 | 手动解锁 | 超时支持 | 多锁同时加锁 | 核心用途 |
|---|---|---|---|---|---|
std::lock_guard | 所有独占锁 | ❌ | ❌ | ❌ | 最简单、最常用(默认首选) |
std::unique_lock | 所有独占锁 | ✅ | ✅ | ❌ | 灵活锁(配合条件变量、手动控制) |
std::shared_lock | shared_mutex | ✅ | ✅ | ❌ | 读写锁的读模式(共享) |
std::scoped_lock | 所有锁 | ❌ | ❌ | ✅ | c++17 同时锁多个锁,防死锁 |
最常用,保护简单共享变量:
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
mutex mtx; // 全局互斥锁
int share_num = 0; // 共享资源
void add_num() {
// 构造自动加锁,离开作用域自动解锁
lock_guard<mutex> lock(mtx);
share_num++;
cout << "线程id: " << this_thread::get_id() << " 数值: " << share_num << endl;
}
int main() {
thread t1(add_num);
thread t2(add_num);
t1.join();
t2.join();
return 0;
}解决递归函数加锁问题:
#include <mutex>
recursive_mutex rmtx;
void func(int n) {
lock_guard<recursive_mutex> lock(rmtx);
if (n > 0) func(n-1); // 同一线程重复加锁,无死锁
}避免永久阻塞:
#include <mutex>
#include <chrono>
timed_mutex tmtx;
void try_lock_func() {
// 尝试加锁,最多等待 100ms
unique_lock<timed_mutex> lock(tmtx, chrono::milliseconds(100));
if (lock.owns_lock()) {
cout << "加锁成功" << endl;
} else {
cout << "加锁超时" << endl;
}
}#include <shared_mutex>
shared_mutex s_mtx;
int data = 0;
// 读线程:共享加锁,多个线程可同时读
void read_data() {
shared_lock<shared_mutex> lock(s_mtx);
cout << "读取数据: " << data << endl;
}
// 写线程:独占加锁,同一时间只能一个写
void write_data(int val) {
unique_lock<shared_mutex> lock(s_mtx);
data = val;
cout << "写入数据: " << data << endl;
}同时加多个锁,避免死锁:
mutex m1, m2;
void safe_lock() {
// 一次性加锁 m1 和 m2,自动避免死锁
scoped_lock lock(m1, m2);
}
lock()/unlock()scoped_lock 同时加锁;std::spin_lock c++20),避免线程切换开销。mutex + lock_guardshared_mutex + shared_lockunique_lockscoped_lockrecursive_mutextimed_mutexstd::mutex + std::lock_guard 足够;-std=c++17 -pthread,代码全平台通用。到此这篇关于关于c++中锁的种类与使用的文章就介绍到这了,更多相关c++锁的种类与使用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论