C++ 编程指南26 - 尽量缩短在临界区(critical section)内的执行时间
一:概述
在临界区中持有互斥锁(mutex)的时间越短,线程之间的等待时间就越少,从而减少线程被挂起和恢复的开销,提高程序的并发性能。
二:示例
在这下面个代码中,整个 do_something()
函数都持有 mutex
,但实际上只有 do1()
需要锁。这会导致不必要的竞争,降低并发性能。
void do_something() // bad
{
std::unique_lock<std::mutex> lck(my_lock);
do0(); // 预处理,不需要锁
do1(); // 需要加锁的事务处理
do2(); // 后续处理,不需要锁
}
减少临界区时间: mutex
只在 do1()
执行时持有,减少竞争,提高并发性能。并且用 std::unique_lock<std::mutex>
确保锁在代码块结束时自动释放,避免死锁。
void do_something() // OK
{
do0(); // 预处理,不需要锁
{
std::unique_lock<std::mutex> lck(my_lock);
do1(); // 需要加锁的事务处理
} // 作用域结束,自动释放锁
do2(); // 后续处理,不需要锁
}
三:总结
一般来说,无法自动检测是否持有 mutex
过长。但可以标记裸露的 lock()
和 unlock()
调用,鼓励使用 RAII 进行资源管理。或者进行代码审查(Code Review) 确保临界区最小化。