做网站应该用什么配置的手提电脑,企业信用信息年度报告公示,wordpress自适应手机主题,山西省住房和城乡建设厅官方网站文章目录 1.创建 std::unique_lock 对象2.自动加锁和解锁3.延迟加锁与手动加解锁4.尝试加锁5.配合条件变量使用6.小结参考文献 std::unique_lock 是 C11 提供的一个用于管理互斥锁的类#xff0c;它提供了更灵活的锁管理功能#xff0c;适用于各种多线程场景。 1.创建 std::u… 文章目录 1.创建 std::unique_lock 对象2.自动加锁和解锁3.延迟加锁与手动加解锁4.尝试加锁5.配合条件变量使用6.小结参考文献 std::unique_lock 是 C11 提供的一个用于管理互斥锁的类它提供了更灵活的锁管理功能适用于各种多线程场景。 1.创建 std::unique_lock 对象
std::unique_lockstd::mutex lock(mutex); // 创建 std::unique_lock 并关联互斥锁 mutex你可以在构造函数中传入一个互斥锁std::mutex 或其它互斥锁类型来创建 std::unique_lock 对象并且会在构造时获取互斥锁的所有权。此时互斥锁被锁住其他线程无法获得锁。
2.自动加锁和解锁
{std::unique_lockstd::mutex lock(mutex); // 自动加锁// 临界区代码
} // 自动解锁使用 std::unique_lock 创建的对象当其生命周期结束时通常是在大括号的作用域结束时会自动解锁互斥锁以确保互斥锁在不再需要时被释放。
3.延迟加锁与手动加解锁
std::unique_lock 还支持在初始化时不立即加锁而是在需要时延迟加锁。这种特性对于一些多线程场景非常有用允许你在获得锁之前执行一些非临界区的操作从而减少锁的持有时间。
创建 std::unique_lock 对象时传入互斥锁但不加锁
std::unique_lockstd::mutex lock(mutex, std::defer_lock);在需要时手动加锁
lock.lock(); // 手动加锁
// 临界区代码
lock.unlock(); // 手动解锁你可以使用 lock() 手动加锁互斥锁然后在互斥锁保护的临界区内执行代码最后使用 unlock() 手动解锁互斥锁。这种方式可以让你更灵活地控制锁的生命周期。
4.尝试加锁
std::unique_lock 还提供了 try_lock() 方法用于尝试加锁如果锁不可用则返回 false如果锁成功获取则返回 true。
std::unique_lockstd::mutex lock(mutex, std::defer_lock);
if (lock.try_lock()) {// 锁成功获取执行临界区代码lock.unlock();
} else {// 锁不可用执行其他逻辑
}5.配合条件变量使用
condition_variable条件变量是 C11 中提供的一种多线程同步机制它允许一个或多个线程等待另一个线程发出的通知以便能够有效地进行线程同步。
条件变量std::condition_variable需要与 std::unique_lock 一起使用以实现线程的等待和通知机制。
std::unique_lockstd::mutex lck(mutex);
while (!condition) {conditionVariable.wait(lock); // 等待条件满足并释放锁
}
// 条件满足重新获取锁并继续执行条件变量的成员函数 wait() 会在阻塞线程的那一刻当线程被添加到等待队列中时函数会自动调用 lck.unlock() 释放锁允许其他锁定的线程继续执行。
一旦收到唤醒通知由其他线程调用 notify_one() 或 notify_all() 通知该函数就会解除阻塞并调用 lck.lock()使 lck 处于与调用该函数时相同的状态然后函数返回。请注意返回前调用 lck.lock() 加锁可能会再次阻塞线程。
为什么条件变量需要互斥锁的配合呢
因为 condition 和等待队列都是多线程的共享资源当访问这些共享资源时需要互斥访问。
6.小结
std::unique_lock 提供了对互斥锁更高级别的控制和灵活性使得多线程编程更加安全和容易。在多数情况下推荐使用 std::unique_lock 而不是直接操作互斥锁因为它能够自动管理锁的生命周期减少了出错的机会。 参考文献
std::unique_lock - cplusplus.com std::condition_variable - cplusplus.com