news 2026/7/7 7:43:57

c++14 四种互斥锁

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
c++14 四种互斥锁

在C++14中,标准库提供了四种互斥锁类型,它们均定义在头文件中,用于多线程编程中保护共享资源,防止数据竞争。以下是具体分类及示例说明:

  1. std::mutex(基础互斥锁)
    功能:最基本的互斥锁,确保同一时间只有一个线程能访问共享资源。
    特点:
    非递归:同一线程重复加锁会导致未定义行为(死锁)。
    无超时机制:调用lock()时若锁已被占用,线程会阻塞直到获取锁。
    示例:
    cpp
    #include
    #include
    #include

std::mutex mtx;
int shared_data = 0;

void increment() {
mtx.lock(); // 加锁
++shared_data; // 访问共享资源
mtx.unlock(); // 解锁
}

int main() {
std::thread t1(increment);
std::thread t2(increment);
t1.join();
t2.join();
std::cout << "Shared data: " << shared_data << std::endl; // 输出 2
return 0;
}
问题:手动管理锁易出错(如未解锁或异常导致死锁)。推荐使用RAII包装类(如std::lock_guard或std::unique_lock)自动管理锁生命周期。
2. std::recursive_mutex(递归互斥锁)
功能:允许同一线程多次加锁,适用于递归调用场景。
特点:
递归支持:同一线程可重复加锁,但需对应次数的解锁。
无超时机制:阻塞式加锁。
示例:
cpp
#include
#include
#include

std::recursive_mutex rmtx;
int shared_data = 0;

void recursive_increment(int n) {
rmtx.lock();
if (n > 0) {
++shared_data;
recursive_increment(n - 1); // 递归调用
}
rmtx.unlock();
}

int main() {
std::thread t1(recursive_increment, 5);
t1.join();
std::cout << "Shared data: " << shared_data << std::endl; // 输出 5
return 0;
}
适用场景:函数内部递归调用且需保护共享资源时(如递归遍历树结构并修改节点数据)。
3. std::timed_mutex(带超时的互斥锁)
功能:在std::mutex基础上增加超时机制,避免无限阻塞。
特点:
支持try_lock_for():尝试在指定时间内获取锁。
支持try_lock_until():尝试在指定时间点前获取锁。
示例:
cpp
#include
#include
#include
#include

std::timed_mutex tmtx;
int shared_data = 0;

void timed_increment() {
if (tmtx.try_lock_for(std::chrono::milliseconds(100))) { // 尝试在100ms内获取锁
++shared_data;
tmtx.unlock();
} else {
std::cout << “Failed to acquire lock within timeout.” << std::endl;
}
}

int main() {
std::thread t1(timed_increment);
std::thread t2(timed_increment);
t1.join();
t2.join();
std::cout << "Shared data: " << shared_data << std::endl; // 输出 1 或 2(取决于锁竞争)
return 0;
}
适用场景:对实时性要求较高的场景(如游戏、高频交易),避免因锁竞争导致线程长时间阻塞。
4. std::recursive_timed_mutex(带超时的递归互斥锁)
功能:结合std::recursive_mutex和std::timed_mutex的特性,支持递归调用和超时机制。
特点:
递归支持:同一线程可多次加锁。
超时支持:通过try_lock_for()或try_lock_until()避免无限阻塞。
示例:
cpp
#include
#include
#include
#include

std::recursive_timed_mutex rtmtx;
int shared_data = 0;

void recursive_timed_increment(int n) {
if (rtmtx.try_lock_for(std::chrono::milliseconds(50))) { // 尝试在50ms内获取锁
if (n > 0) {
++shared_data;
recursive_timed_increment(n - 1); // 递归调用
}
rtmtx.unlock();
} else {
std::cout << “Failed to acquire lock within timeout.” << std::endl;
}
}

int main() {
std::thread t1(recursive_timed_increment, 3);
t1.join();
std::cout << "Shared data: " << shared_data << std::endl; // 输出 3 或因超时未完成
return 0;
}
适用场景:递归调用且需避免死锁的实时系统(如嵌入式开发)。
总结
锁类型 核心特性 适用场景
std::mutex 基础互斥,非递归,无超时 简单临界区保护
std::recursive_mutex 递归支持,无超时 递归调用保护共享资源
std::timed_mutex 带超时,非递归 实时系统,避免无限阻塞
std::recursive_timed_mutex 递归+超时 递归调用且需超时控制的场景
推荐实践:

优先使用RAII包装类:如std::lock_guard或std::unique_lock自动管理锁生命周期,避免手动解锁错误。
cpp
std::mutex mtx;
void safe_increment() {
std::lock_guardstd::mutex lock(mtx); // 自动加锁/解锁
++shared_data;
}
根据需求选择锁类型:
无需递归或超时 → std::mutex。
递归调用 → std::recursive_mutex。
实时性要求高 → std::timed_mutex或std::recursive_timed_mutex。
避免锁竞争:缩小临界区范围,减少锁持有时间,提升并发性能。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 17:30:04

HuggingFace镜像网站搜索功能使用技巧

HuggingFace镜像网站搜索功能使用技巧 在AI研发日益依赖预训练模型的今天&#xff0c;一个高效的模型获取流程往往决定了项目能否快速启动。HuggingFace作为全球最大的开源模型平台&#xff0c;汇聚了数以万计的深度学习模型与数据集&#xff0c;但其原始站点在国内访问时常面…

作者头像 李华
网站建设 2026/7/7 8:06:32

Dify平台对国产大模型的支持现状与扩展建议

Dify平台对国产大模型的支持现状与扩展建议 在AI应用从实验室走向产线的今天&#xff0c;一个现实问题摆在企业面前&#xff1a;如何让通义千问、百川、讯飞星火这些能力不俗的国产大模型真正用起来&#xff1f;不是跑个demo&#xff0c;而是嵌入业务流程、支撑客服系统、处理合…

作者头像 李华
网站建设 2026/7/7 10:33:40

从零开始配置PaddlePaddle开发环境:ubuntu安装+cuda安装一站式教程

从零开始配置PaddlePaddle开发环境&#xff1a;Ubuntu安装CUDA安装一站式教程 在深度学习项目启动的第一天&#xff0c;很多开发者都会遇到一个看似简单却极易“踩坑”的问题&#xff1a;如何让PaddlePaddle真正跑在GPU上&#xff1f;明明装了CUDA、也装了paddlepaddle-gpu&am…

作者头像 李华
网站建设 2026/7/7 19:27:56

LobeChat能否实现SQL注入检测?安全编码辅助工具

LobeChat能否实现SQL注入检测&#xff1f;安全编码辅助工具 在现代Web应用开发中&#xff0c;一个看似普通的用户查询接口&#xff0c;可能正悄悄打开通往数据库的后门。比如这行代码&#xff1a; db.query(SELECT * FROM users WHERE id ${req.query.id})它简洁、直观&…

作者头像 李华
网站建设 2026/7/6 22:41:51

Kafka消费者消费失败问题的深度解码与治理实践

一、背景kafka消息总量10亿/天&#xff0c;每分钟生成70万条消息&#xff0c;生成环境部署了12个服务&#xff0c;消费2个Topic&#xff0c;每个Topic部署12个分区二、现象问题消费者方面1、单个服务&#xff0c;同时消费2个不同Topic的2个分区&#xff0c;一个分区消费正常&am…

作者头像 李华