当前位置: 首页 > news >正文

C++常用锁总结

一、基础互斥锁 std::mutex

用途:保护共享资源的基础互斥锁

#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;
int shared_data = 0;void increment() {mtx.lock();for (int i = 0; i < 100000; ++i) {++shared_data;}mtx.unlock();
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Final value: " << shared_data << std::endl;// 正确输出 200000
}

编译命令

g++ -std=c++11 -pthread example.cpp

二、RAII 锁 std::lock_guard

用途:自动管理锁的生命周期

#include <mutex>
#include <vector>
#include <thread>std::mutex mtx;
std::vector<int> vec;void add_element(int val) {std::lock_guard<std::mutex> lock(mtx); // 自动加锁/解锁vec.push_back(val);
}int main() {std::thread threads[5];for (int i = 0; i < 5; ++i) {threads[i] = std::thread(add_element, i);}for (auto& t : threads) t.join();std::cout << "Vector size: " << vec.size() << std::endl;// 正确输出 5
}

三、灵活锁 std::unique_lock

用途:支持延迟锁定和所有权转移

#include <mutex>
#include <queue>std::mutex mtx;
std::queue<int> data_queue;void data_preparation() {for (int i = 0; i < 10; ++i) {std::unique_lock<std::mutex> lock(mtx);data_queue.push(i);lock.unlock(); // 显式解锁std::this_thread::sleep_for(std::chrono::milliseconds(10));}
}void data_processing() {while (true) {std::unique_lock<std::mutex> lock(mtx);if (!data_queue.empty()) {int data = data_queue.front();data_queue.pop();lock.unlock(); // 提前解锁std::cout << "Processed: " << data << std::endl;} else {lock.unlock();break;}}
}int main() {std::thread t1(data_preparation);std::thread t2(data_processing);t1.join();t2.join();
}

四、递归锁 std::recursive_mutex

用途:允许同一线程多次加锁

#include <mutex>
#include <thread>std::recursive_mutex rmtx;void recursive_func(int n) {if (n <= 0) return;rmtx.lock();std::cout << "Locked, n = " << n << std::endl;recursive_func(n - 1);rmtx.unlock();
}int main() {std::thread t(recursive_func, 3);t.join();// 输出 3次加锁信息
}

五、超时锁 std::timed_mutex

用途:尝试获取锁时设置超时

#include <mutex>
#include <chrono>
#include <thread>std::timed_mutex tmtx;void timed_job() {auto start = std::chrono::steady_clock::now();if (tmtx.try_lock_for(std::chrono::milliseconds(100))) {std::cout << "Got lock after waiting\n";std::this_thread::sleep_for(std::chrono::milliseconds(200));tmtx.unlock();} else {auto end = std::chrono::steady_clock::now();auto diff = end - start;std::cout << "Timeout after " << std::chrono::duration<double, std::milli>(diff).count()<< "ms\n";}
}int main() {std::thread t1(timed_job);std::thread t2(timed_job);t1.join();t2.join();
}

六、共享锁 std::shared_mutex (C++17)

用途:实现读写锁(读者共享,写者互斥)

#include <shared_mutex>
#include <thread>
#include <vector>std::shared_mutex smtx;
std::string data;void reader(int id) {std::shared_lock<std::shared_mutex> lock(smtx);std::cout << "Reader " << id << " sees: " << data << "\n";
}void writer() {std::unique_lock<std::shared_mutex> lock(smtx);data = "New data";std::cout << "Writer updated data\n";
}int main() {std::vector<std::thread> readers;for (int i = 0; i < 5; ++i) {readers.emplace_back(reader, i);}std::thread w(writer);for (auto& r : readers) r.join();w.join();
}

七、条件变量 std::condition_variable

用途:线程间条件同步

#include <condition_variable>
#include <queue>std::mutex mtx;
std::queue<int> data_queue;
std::condition_variable cv;void producer() {for (int i = 0; i < 5; ++i) {std::this_thread::sleep_for(std::chrono::seconds(1));{std::lock_guard<std::mutex> lock(mtx);data_queue.push(i);}cv.notify_one();}
}void consumer() {while (true) {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, []{ return !data_queue.empty(); });int data = data_queue.front();data_queue.pop();std::cout << "Consumed: " << data << std::endl;if (data == 4) break;}
}int main() {std::thread p(producer);std::thread c(consumer);p.join();c.join();
}

关键总结表格

锁类型特性适用场景
std::mutex基础互斥锁简单资源保护
std::lock_guardRAII自动管理局部作用域自动解锁
std::unique_lock灵活所有权控制需要手动控制解锁时机
std::recursive_mutex同一线程可重入递归调用场景
std::timed_mutex支持超时尝试避免死锁等待
std::shared_mutex读写分离读多写少场景
std::condition_variable线程间条件同步生产者-消费者模式

编译注意事项

  1. 必须添加 -pthread 编译选项
  2. C++17 特性需要 -std=c++17

相关文章:

  • @JsonView + 单一 DTO:如何实现多场景 JSON 字段动态渲染
  • Next.js 技术详解:构建现代化 Web 应用的全栈框架
  • 使用Service发布应用程序
  • 探索C++中的数据结构:栈(Stack)的奥秘
  • 数据类型相关问题导致的索引失效 | OceanBase SQL 优化实践
  • 【C到Java的深度跃迁:从指针到对象,从过程到生态】第二模块·语法迁移篇 —— 第六章 函数革命:从过程到方法的重生
  • 决战浏览器渲染:减少重绘(Repaint)与重排(Reflow)的性能优化策略
  • 在服务器上安装redis
  • vLLM V1:性能优化与集群扩展的深度解析
  • 数据结构基本概念
  • k8s低版本1.15安装prometheus+grafana进行Spring boot数据采集
  • test ssl java
  • Java 序列化与反序列化终极解析
  • pointnet pointnet++论文笔记
  • 麒麟操作系统漏洞修复保姆级教程弱(一)算法漏洞修复
  • Vue3 + TypeScript中provide和inject的用法示例
  • 基于ubuntu24.10安装NACOS2.5.1的简介
  • 第18周:对于ResNeXt-50算法的思考
  • 51单片机实验一:点亮led灯
  • 2025妈妈杯Mathorcup数学建模竞赛选题建议+初步分析
  • 天工摘得全球首个人形机器人半马冠军:中国机器人产业正努力跑向人机共生社会
  • 解读丨连续两日施压,特朗普为何着急让美联储降息
  • 商务部新闻发言人就美对我海事、物流和造船等领域宣布最终措施答记者问
  • 美方将对中国制造船只征收“港口费”,外交部:损人害己
  • 生于1984年,郭宝任湖北黄石市副市长
  • 警方通报一起交通事故:6人受伤,系司机启动车辆时操作不当