🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## std::mutx - 但是在实际编写代码的过程中,最好不去直接调用成员函数, 因为调用成员函数就需要在每个临界区的出口处调用`unlock()`, - 会产生异常 ``` #include <iostream> #include <mutex> #include <thread> int v = 1; void critical_section(int change_v) { // 使用 static ,想相当于全局变量 static std::mutex mtx; // 执行竞争操作 mtx.lock(); v = change_v; mtx.unlock(); } int main() { std::thread t1(critical_section, 2), t2(critical_section, 3); t1.join(); t2.join(); std::cout << v << std::endl; return 0; } ``` ## std::lock_guard - C++11 还为互斥量提供了一个 RAII 语法的模板类 std::lock_guard。 RAII 在不失代码简洁性的同时,很好的保证了代码的异常安全性 - 此函数相当于 go的 defer,在函数退出时,触发 在 RAII 用法下,对于临界区的互斥量的创建只需要在作用域的开始部分, ``` #include <iostream> #include <mutex> #include <thread> int v = 1; void critical_section(int change_v) { static std::mutex mtx; std::lock_guard<std::mutex> lock(mtx); // 执行竞争操作 v = change_v; // 离开此作用域后 mtx 会被释放 } int main() { std::thread t1(critical_section, 2), t2(critical_section, 3); t1.join(); t2.join(); std::cout << v << std::endl; return 0; } ``` ## std::unique_lock -推荐 而`std::unique_lock`则是相对于`std::lock_guard`出现的,`std::unique_lock`更加灵活,`std::unique_lock`的对象会以独占所有权(没有其他的`unique_lock`对象同时拥有某个`mutex`对象的所有权) 的方式管理`mutex`对象上的上锁和解锁的操作。所以在并发编程中,推荐使用`std::unique_lock` - unique_lock中的unique表示独占所有权。 - unique_lock独占的是mutex对象,就是对mutex锁的独占。 - `std::unique_lock`可以在声明后的任意位置调用, 可以缩小锁的作用范围,提供更高的并发度 ``` #include <iostream> #include<thread> #include<mutex> #include <Windows.h> int number; void handle() { static std::mutex mux; std::unique_lock<std::mutex> lock(mux); number++; std::cout << number<<"\n"; lock.unlock(); // lock.unlock(); 如果下面要执行的共同代码,可以不释放, // todo code // 可以再次进行加锁 lock.lock(); number++; std::cout << number << "\n"; } int main() { std::thread t1(handle), t2(handle); t1.join(); t2.join(); return 0; } ```