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_guard | RAII自动管理 | 局部作用域自动解锁 |
std::unique_lock | 灵活所有权控制 | 需要手动控制解锁时机 |
std::recursive_mutex | 同一线程可重入 | 递归调用场景 |
std::timed_mutex | 支持超时尝试 | 避免死锁等待 |
std::shared_mutex | 读写分离 | 读多写少场景 |
std::condition_variable | 线程间条件同步 | 生产者-消费者模式 |
编译注意事项:
- 必须添加
-pthread
编译选项 - C++17 特性需要
-std=c++17