std::mutex的使用备忘

在实际测试中,与使用自实现的自旋做同步比较(看上也是自旋),std::mutex在效率上没有大的差异。

但是当出现竞争时,std::mutex的lock会完全的等待,此时CPU利用率会很高,当然其等待也是有收益的:效率最高。

 

但是,在一般的应用里,我们能查看任何管理器时,我们总是蜜汁不希望CPU满载(不想让风扇狂转?)

 

降低CPU负载的套路是:使用trylock。不光出让时间片,还得退出竞争。

当然,随之带来的也是效率的下降(-15%?)

 

我们的测试是基于4C16G硬件。

应用的测试方案是下图(3P3C):

<think>好的,我现在需要回答用户关于C++中static std::mutex的定义和用法的问题。首先,我要回忆一下std::mutex的基本概念。std::mutex是C++标准库中用于多线程同步的互斥量,用于保护共享资源不被同时访问。用户提到的是static std::mutex,这意味着这个互斥量是静态的,可能属于某个类或函数内的静态成员。 接下来,我需要确认static std::mutex的定义方式。根据C++的规则,静态成员变量需要在类外进行定义和初始化。例如,在类内部声明为static std::mutex mtx;,然后在类外部定义std::mutex ClassName::mtx;。同时,C++17引入了内联变量的支持,允许在声明时直接初始化,这可能简化代码。 然后,关于用法,静态互斥量通常用于保护类的静态成员或全局共享资源。比如在多线程环境中,多个线程访问某个静态变量时,需要用互斥量进行同步。例如,在单例模式中,双重检查锁定可能会用到静态互斥量来确保线程安全。 还要注意,使用std::mutex时需要包含<mutex>头文件,并且C++11及以上版本支持。此外,互斥量的锁定和解锁通常通过RAII机制管理,比如std::lock_guard或std::unique_lock,以避免忘记解锁导致的死锁问题。 用户提供的引用中提到,std::mutex是独占互斥量,不能递归使用,所以需要确保同一线程内不会重复加锁。另外,引用中的ComputationCache结构体可能是一个缓存类,但其中没有使用互斥量,因此如果在多线程环境中使用这个类,就需要添加互斥量来保护cached_x和cached_result的访问。例如,在compute函数中检查缓存时,需要加锁确保线程安全。 可能遇到的问题包括静态成员的初始化顺序问题,尤其是在不同的编译单元中。因此,需要确保静态互斥量在使用前已经被正确初始化。此外,静态成员的生命周期是整个程序运行期间,所以需要小心避免资源泄漏。 最后,生成相关问题时,需要考虑用户可能想进一步了解的内容,比如静态互斥量的初始化方法、线程安全的单例模式、RAII机制的应用,以及不同互斥量类型的区别等。</think>### C++中static std::mutex的定义与用法 #### 1. **定义方式** 在C++中,`static std::mutex`通常用于类内或全局作用域,以保护共享资源的线程安全访问。其定义需遵循以下规则: - **类内静态成员**:在类内声明为`static`,并在类外进行初始化(C++17前需要显式定义,C++17支持内联初始化)。 ```cpp class MyClass { public: static std::mutex mtx; // 类内声明 // ... }; // 类外定义(C++17前必需) std::mutex MyClass::mtx; ``` - **全局静态互斥量**:在函数或全局作用域中使用`static`关键字定义。 ```cpp static std::mutex global_mtx; // 全局静态互斥量 ``` #### 2. **使用场景** - **保护静态成员变量**:当多个线程需要访问类的静态成员时,需用互斥量同步。 - **单例模式**:实现线程安全的单例对象初始化。 - **全局资源共享**:如日志写入、缓存访问等。 #### 3. **具体用法示例** ```cpp #include <iostream> #include <mutex> #include <thread> class Counter { public: static int value; static std::mutex mtx; static void increment() { std::lock_guard<std::mutex> lock(mtx); // RAII自动加锁/解锁 value++; } }; int Counter::value = 0; std::mutex Counter::mtx; // 类外定义静态成员 int main() { std::thread t1([]() { for (int i = 0; i < 1000; ++i) Counter::increment(); }); std::thread t2([]() { for (int i = 0; i < 1000; ++i) Counter::increment(); }); t1.join(); t2.join(); std::cout << "Final value: " << Counter::value << std::endl; // 输出2000 return 0; } ``` 此示例中,`std::lock_guard`通过RAII机制确保互斥量的自动释放,避免死锁[^2]。 #### 4. **注意事项** - **初始化顺序**:静态互斥量的初始化可能受编译单元影响,需确保在使用前已构造。 - **递归锁定**:`std::mutex`不可递归锁定,如需递归特性,改用`std::recursive_mutex`[^2]。 - **超时控制**:若需超时功能,可选用`std::timed_mutex`。 #### 5. **结合用户提供的代码** 参考用户提供的`ComputationCache`结构体[^3],若需线程安全,可修改为: ```cpp struct ComputationCache { static std::mutex mtx; // 添加静态互斥量 double cached_x = 0.0; double cached_result = 0.0; double compute(double x) { std::lock_guard<std::mutex> lock(mtx); if (cached_x != x) { cached_x = x; cached_result = /* 复杂计算 */; } return cached_result; } }; // 类外定义静态成员 std::mutex ComputationCache::mtx; ``` --- 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值