C++11 新特性:锁

在多线程编程中,锁是用于控制对共享资源的访问的一种机制。C++11 引入了一系列新特性来支持线程同步,提供了更高效、更安全的锁管理。本文将介绍 C++11 中的三种重要锁类:std::mutexstd::lock_guardstd::unique_lock,以及它们的使用方法和特点。

1. std::mutex

std::mutex 是 C++11 引入的标准互斥锁,用于保护共享资源,防止多个线程同时访问引发的数据竞争。std::mutex 提供了基本的锁功能,允许一个线程独占对共享资源的访问权。

示例:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void print_message(const std::string& message) {
std::lock_guard<std::mutex> lock(mtx); // 加锁
std::cout << message << std::endl;
}

在这个示例中,std::mutex 对象 mtx 用于保护 print_message 函数中的 std::cout,确保同一时间只有一个线程可以打印消息。

2. std::lock_guard

std::lock_guard 是一种基于 RAII(资源获取即初始化) 的简单锁管理器。它在构造时自动获取锁,在作用域结束时自动释放锁,确保锁在临界区内被正确持有和释放。

示例:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void example() {
std::lock_guard<std::mutex> lock(mtx); // 自动加锁
// 临界区操作
std::cout << "In critical section" << std::endl;
} // lock 离开作用域时自动解锁

在这个示例中,std::lock_guard 对象 lock 在创建时自动加锁,离开作用域时自动解锁,简化了锁的管理。

3. std::unique_lock

std::unique_lock 是一个更灵活的锁管理器,相比 std::lock_guard,它支持延迟加锁、手动解锁和条件变量等功能,适用于更复杂的锁控制场景。

主要功能:

  • 延迟加锁:可以在创建时不立即加锁,稍后通过 lock() 方法手动加锁。
  • 显式解锁:可以通过 unlock() 方法手动解锁,允许在需要时提前释放锁。
  • 所有权转移:支持通过 std::move 将锁的所有权从一个 std::unique_lock 实例转移到另一个。

示例:

延迟加锁

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void example() {
std::unique_lock<std::mutex> lock(mtx, std::defer_lock); // 延迟加锁
lock.lock(); // 手动加锁

// 临界区操作
std::cout << "In critical section" << std::endl;

lock.unlock(); // 手动解锁
} // lock 离开作用域时自动解锁

在这个示例中,std::unique_lock 被初始化为延迟加锁,锁在需要时显式加锁和解锁。

锁的所有权转移

#include <iostream>
#include <thread>
#include <mutex>

void func(std::unique_lock<std::mutex> lock) {
// lock 持有互斥锁
std::cout << "In critical section in func" << std::endl;
} // lock 离开作用域时解锁

int main() {
std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx); // 加锁
func(std::move(lock)); // 将锁的所有权转移到 func

// lock 在这里是将亡值,已经不再持有锁
}

在这个示例中,std::move(lock) 将锁的所有权传递给 func 函数。func 函数在其作用域内持有锁,main 函数中的 lock 变成将亡值,不能再使用。

总结

C++11 引入的锁机制使多线程编程变得更加简单和安全:

  • std::mutex 提供基本的互斥功能,用于保护共享资源。
  • std::lock_guard 基于 RAII 机制,简化了锁的管理,确保在作用域内持有锁。
  • std::unique_lock 提供了更高的灵活性,支持延迟加锁、手动解锁和锁所有权转移,适用于更复杂的锁控制需求。

了解这些新特性,并根据实际需要选择合适的锁管理方式,将帮助你在多线程编程中更有效地管理共享资源和确保线程安全。


已发布

分类

来自

标签:

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注