在 C++ 中,std::unique_lock
是一个 RAII(资源获取即初始化)风格的类,用于管理互斥量的锁定和解锁。通常情况下,std::unique_lock
会在其作用域结束时自动释放锁,即在其析构函数中自动调用 unlock()
方法释放锁。
然而,如果需要手动控制锁的释放,可以通过 unlock()
方法手动释放锁,而不必等到 std::unique_lock
对象销毁时自动释放。以下是一个示例:
#include <iostream>
#include <mutex>
#include <thread>
std::mutex mtx;
void doWork() {
std::unique_lock<std::mutex> lock(mtx);
// 执行一些需要加锁的操作
// 手动释放锁
lock.unlock();
// 在没有锁的情况下执行一些操作
// 再次锁定
lock.lock();
// 继续执行需要加锁的操作
}
int main() {
std::thread t(doWork);
t.join();
return 0;
}
在上面的示例中,我们创建了一个 std::unique_lock
对象 lock
,并在 doWork()
函数中使用它来管理互斥量 mtx
。我们在一些操作后手动调用了 unlock()
方法释放锁,然后在需要时再次调用 lock()
方法重新锁定互斥量。
虽然可以手动释放和重新获取锁,但建议在可能的情况下遵循 RAII 原则,让 std::unique_lock
对象自动管理锁的生命周期,从而避免忘记释放锁而导致的死锁等问题。
std::unique_lockstd::mutex lock(g_currentDeviceConfig->mtx); 如何 缩小锁定的范围
要缩小锁定的范围,可以在需要锁定的代码块内创建 std::unique_lock
对象,这样锁的生命周期将仅限于该代码块内。这种方法可以避免在整个函数范围内持有锁,从而提高程序的性能和减少潜在的锁竞争。
下面是一个示例,演示如何在需要时缩小锁定的范围:
#include <iostream>
#include <mutex>
struct DeviceConfig {
std::mutex mtx;
int data;
};
DeviceConfig* g_currentDeviceConfig = new DeviceConfig();
void doWork() {
// 在需要锁定的代码块内创建 std::unique_lock 对象,锁的生命周期仅限于该代码块
{
std::unique_lock<std::mutex> lock(g_currentDeviceConfig->mtx);
// 执行一些需要加锁的操作
g_currentDeviceConfig->data = 42;
} // 在这里锁会自动释放
// 在没有锁的情况下执行一些操作
}
int main() {
doWork();
return 0;
}
在上面的示例中,我们在 doWork()
函数中的代码块内创建了 std::unique_lock
对象 lock
,这样锁的生命周期仅限于该代码块。当程序执行完代码块后,std::unique_lock
对象 lock
的析构函数会自动释放锁,从而避免在整个函数范围内持有锁。
通过在需要时在代码块内创建 std::unique_lock
对象,可以有效地缩小锁定的范围,提高程序的性能并减少潜在的锁竞争。