C++ mutex 学习笔记
1. 了解 C++ 中的互斥锁(mutex)
- 作用:互斥锁是一种用于保护共享资源不被多个线程同时访问的同步机制。它可以确保在任意时刻只有一个线程可以访问共享资源,从而避免数据竞争和不一致性。
- 优势:提供了一种简单而有效的方法来保护共享资源,确保线程安全性。
- 发展历程:互斥锁是多线程编程中常用的同步机制,C++ 标准库提供了
std::mutex
类来实现互斥锁。
示例代码:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void thread_function(int id) {
mtx.lock(); // 加锁
std::cout << "Thread " << id << " is executing..." << std::endl;
mtx.unlock(); // 解锁
}
int main() {
std::thread t1(thread_function, 1);
std::thread t2(thread_function, 2);
t1.join();
t2.join();
return 0;
}
2. 学习 C++ 中的互斥锁的多种应用场景
- 保护共享资源:互斥锁常用于保护共享资源,确保多个线程不会同时访问或修改共享数据,防止数据竞争。
- 线程同步:互斥锁可用于实现线程之间的同步,确保多个线程按照指定顺序执行,避免并发执行带来的问题。
- 避免死锁:正确使用互斥锁可以避免死锁问题,确保线程能够正常执行并释放锁。
示例代码:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
int shared_data = 0;
void increment_shared_data() {
mtx.lock();
++shared_data;
mtx.unlock();
}
int main() {
std::thread t1(increment_shared_data);
std::thread t2(increment_shared_data);
t1.join();
t2.join();
std::cout << "Shared data: " << shared_data << std::endl;
return 0;
}
3. 掌握 C++ 中的互斥锁的使用技巧
- 加锁解锁:互斥锁的正确使用包括加锁和解锁两个步骤,确保在访问共享资源时正确加锁,在不需要访问时及时解锁。
- 避免死锁:避免出现死锁情况,即多个线程相互等待对方释放资源而无法继续执行的情况,可以使用
std::lock_guard
类来自动管理互斥锁的加锁和解锁。 - 递归锁:互斥锁也支持递归锁,允许同一个线程多次对同一个互斥锁进行加锁,但需要小心避免死锁。
示例代码:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void recursive_mutex_function(int count) {
if (count <= 0) {
return;
}
mtx.lock();
std::cout << "Mutex locked, count = " << count << std::endl;
recursive_mutex_function(count - 1);
mtx.unlock();
}
int main() {
recursive_mutex_function(5);
return 0;
}
4. 实战案例分析
- 多线程数据同步:使用互斥锁确保多个线程对共享数据的安全访问。
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
int shared_data = 0;
void increment_shared_data() {
for (int i = 0; i < 1000; ++i) {
mtx.lock();
++shared_data;
mtx.unlock();
}
}
int main() {
std::thread t1(increment_shared_data);
std::thread t2(increment_shared_data);
t1.join();
t2.join();
std::cout << "Shared data: " << shared_data << std::endl;
return 0;
}
- 线程安全容器:使用互斥锁保护标准库提供的线程安全容器,实现多线程环境下的安全操作。
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
std::mutex mtx;
std::vector<int> data;
void insert_data(int value) {
mtx.lock();
data.push_back(value);
mtx.unlock();
}
int main() {
std::thread t1([](){
for (int i = 0; i < 1000; ++i) {
insert_data(i);
}
});
std::thread t2([](){
for (int i = 1000; i < 2000; ++i) {
insert_data(i);
}
});
t1.join();
t2.join();
// 输出线程安全容器中的数据
for (const auto& value : data) {
std::cout << value << " ";
}
std::cout << std::endl;
return 0;
}
- 避免资源竞争:使用互斥锁避免资源竞争和死锁问题,确保多线程程序的稳定性和可靠性。
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx1, mtx2;
void function1() {
mtx1.lock();
std::cout << "Function 1 acquired mutex 1" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟耗时操作
mtx2.lock();
std::cout << "Function 1 acquired mutex 2" << std::endl;
mtx2.unlock();
mtx1.unlock();
}
void function2() {
mtx2.lock();
std::cout << "Function 2 acquired mutex 2" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟耗时操作
mtx1.lock();
std::cout << "Function 2 acquired mutex 1" << std::endl;
mtx1.unlock();
mtx2.unlock();
}
int main() {
std::thread t1(function1);
std::thread t2(function2);
t1.join();
t2.join();
return 0;
}
通过学习和掌握 C++ 中的互斥锁(mutex),可以更好地保护共享资源,确保多线程程序的正确性和稳定性。