C++ 锁
C++ 中的锁主要用于多线程编程,以确保在并发环境下对共享资源的安全访问。以下是一些关键概念和常用的锁类型:
1. Mutex(互斥锁)
std::mutex
是最基础的互斥锁,主要用于保护共享数据以防止数据竞争。
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
int shared_counter = 0;
void increment_counter() {
for (int i = 0; i < 1000; ++i) {
mtx.lock();
++shared_counter;
mtx.unlock();
}
}
int main() {
std::thread t1(increment_counter);
std::thread t2(increment_counter);
t1.join();
t2.join();
std::cout << "Final counter value: " << shared_counter << std::endl;
return 0;
}
2. std::lock_guard
std::lock_guard 是一个封装类,它在构造时锁定互斥锁,在析构时解锁互斥锁,确保在任何情况下都能正确释放锁。
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
int shared_counter = 0;
void increment_counter(int id) {
for (int i = 0; i < 1000; ++i) {
std::lock_guard<std::mutex> lock(mtx);
++shared_counter;
}
}
int main() {
std::thread t1(increment_counter);
std::thread t2(increment_counter);
t1.join();
t2.join();
return 0;
}
3. std::unique_lock
std::unique_lock 比 std::lock_guard 更加灵活,支持手动加锁和解锁操作。
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
int shared_counter = 0;
void increment_counter(int id) {
for (int i = 0; i < 1000; ++i) {
std::unique_lock<std::mutex> lock(mtx);
++shared_counter;
std::cout << "Thread " << id << " incremented counter to " << shared_counter << std::endl;
// 可以在此处手动解锁
// lock.unlock();
// 其他代码
// lock.lock();
}
}
int main() {
std::thread t1(increment_counter, 1);
std::thread t2(increment_counter, 2);
t1.join();
t2.join();
std::cout << "Final counter value: " << shared_counter << std::endl;
return 0;
}
4. std::shared_mutex(共享互斥锁)
std::shared_mutex 允许多个线程同时读取共享数据,但只允许一个线程写入。
#include <iostream>
#include <thread>
#include <shared_mutex>
#include <vector>
#include <chrono>
std::shared_mutex mtx;
int shared_counter = 0;
// 读取共享资源的函数
void read_counter(int id) {
for (int i = 0; i < 10; ++i) {
std::shared_lock<std::shared_mutex> lock(mtx);
std::cout << "Reader " << id << " reads counter: " << shared_counter << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
// 写入共享资源的函数
void write_counter(int id) {
for (int i = 0; i < 5; ++i) {
std::unique_lock<std::shared_mutex> lock(mtx);
++shared_counter;
std::cout << "Writer " << id << " increments counter to: " << shared_counter << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}
int main() {
std::vector<std::thread> readers;
std::vector<std::thread> writers;
// 启动3个读线程
for (int i = 0; i < 3; ++i) {
readers.emplace_back(read_counter, i + 1);
}
// 启动2个写线程
for (int i = 0; i < 2; ++i) {
writers.emplace_back(write_counter, i + 1);
}
// 等待所有读线程完成
for (auto& reader : readers) {
reader.join();
}
// 等待所有写线程完成
for (auto& writer : writers) {
writer.join();
}
std::cout << "Final counter value: " << shared_counter << std::endl;
return 0;
}
5. std::condition_variable(条件变量)
条件变量用于在线程间同步,通过等待特定条件的发生来控制线程的执行。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void print_id(int id) {
std::unique_lock<std::mutex> lck(mtx);
while (!ready) cv.wait(lck); // 等待ready变为true
// 打印线程ID
std::cout << "Thread " << id << '\n';
}
void go() {
std::unique_lock<std::mutex> lck(mtx);
ready = true;
cv.notify_all(); // 通知所有等待线程
}
int main() {
std::thread threads[10];
// 创建10个线程
for (int i = 0; i < 10; ++i)
threads[i] = std::thread(print_id, i);
std::cout << "10 threads ready to race...\n";
go(); // 通知所有线程
for (auto& th : threads) th.join();
return 0;
}