C++ 线程(2)

一、Mutexes(互斥量类:用于独占式访问共享资源)

1. mutex(基础互斥量类)


作用:最基础的互斥量,保证同一时间只有一个线程能获取锁。

2. recursive_mutex(递归互斥量类)


作用:允许同一线程多次获取锁(需对应次数的unlock()释放),避免同一线程重复加锁导致的死锁。
核心成员函数:与mutex完全一致(lock()/unlock()/try_lock()),仅逻辑上支持 “同一线程递归加锁”。

3. timed_mutex(带超时的互斥量类)


作用:在mutex基础上,支持 “超时尝试获取锁”(避免无限阻塞)。
核心成员函数(含mutex的lock()/unlock()/try_lock())

1. try_lock_for()
template <class Rep, class Period>
bool try_lock_for(const std::chrono::duration<Rep, Period>& timeout_duration);

template <class Rep, class Period>:这是模板参数,对应 C++ 时间库的 “时长类型”:
Rep:表示 “计数的类型”(比如int、long long,用来存 “多少个时间单位”);
Period:表示 “时间单位的周期”(比如std::ratio<1>代表 1 秒,std::ratio<1, 1000>代表 1 毫秒)。
参数timeout_duration:要等待的相对时长(比如std::chrono::seconds(2)代表等 2 秒)。
返回值bool:true= 在时长内成功抢到锁;false= 超时没抢到锁。

2. try_lock_until()
template <class Clock, class Duration>
bool try_lock_until(const std::chrono::time_point<Clock, Duration>& timeout_time);

template <class Clock, class Duration>:模板参数对应 C++ 时间库的 “时间点类型”:
Clock:时钟类型(比如std::chrono::steady_clock是 “稳定时钟”,不会受系统时间调整影响);
Duration:时间点的 “时间间隔类型”(和try_lock_for()的duration是同一个概念)。
参数timeout_time:要等待的绝对时间点(比如std::chrono::steady_clock::now() + std::chrono::seconds(3)代表 “现在之后 3 秒” 这个时刻)。
返回值bool:true= 在时间点前成功抢到锁;false= 到了时间点还没抢到锁。

4. recursive_timed_mutex(递归 + 带超时的互斥量类)


作用:结合recursive_mutex(递归加锁)和timed_mutex(超时尝试)的特性。
核心成员函数:包含recursive_mutex的所有函数 + timed_mutex的try_lock_for()/try_lock_until()。

std::recursive_timed_mutex rtm;

void test_try_lock(int depth) {
	if (rtm.try_lock_for(std::chrono::seconds(1))) {
		std::cout << "深度" << depth << ":成功拿到锁\n";

		if (depth < 2) {
			test_try_lock(depth + 1);
		}

		rtm.unlock();
	}
	else {
		std::cout << "深度" << depth << ":等了1秒没拿到锁,超时!\n";
	}
}

int main() {
	std::cout << "=== 正常递归测试 ===\n";
	test_try_lock(0);

	std::cout << "\n=== 超时测试 ===\n";
	rtm.lock();
	std::thread t(test_try_lock, 0);
	t.join();
	rtm.unlock();

	return 0;
}

二、Locks(锁模板类:RAII 风格管理互斥量,避免忘记解锁)

“RAII” 指:构造时自动加锁,析构时自动解锁,保证异常场景下锁也能释放。


1. lock_guard(简单 RAII 锁模板类)


作用:轻量、简单的 RAII 锁,仅支持 “构造加锁、析构解锁”。
模板参数:Mutex(互斥量类型,如std::mutex)。

2. unique_lock(灵活 RAII 锁模板类)


作用:比lock_guard更灵活,支持 “延迟加锁、尝试加锁、超时加锁、转移锁所有权”。
模板参数:Mutex(互斥量类型)。

构造函数

成员函数
维度    lock_guard   unique_lock
构造方式       必须在构造时绑定锁并加锁(或用adopt_lock表示已加锁)支持延迟加锁(用defer_lock参数,构造时不自动加锁,后续手动lock())
所有权转移      不可移动、不可复制(锁的管理权限不能转) 可以移动(比如作为函数返回值传递锁的管理权限),但不可复制
功能支持        仅支持 “自动加 / 解锁”,无额外操作支持try_lock()、try_lock_for()(超时抢锁)、手动lock()/unlock()等
开销     极轻量(几乎无额外开销)  有少量额外开销(因为要维护锁的状态)
适用场景       简单的 “加锁后执行一段代码就解锁” 的场景 需要灵活控制锁(比如配合条件变量condition_variable、延迟加锁、超时抢锁)的场景

简单场景(只需要 “加锁→执行→解锁”):用lock_guard(高效轻量)。
灵活场景(延迟加锁、超时抢锁、配合条件变量):用unique_lock(功能丰富)。

std::mutex mtx;
void task() {
    std::lock_guard<std::mutex> guard(mtx); // 构造时自动加锁
    // 执行临界区代码
} // 析构时自动解锁
std::mutex mtx;
void task() {
    // 延迟加锁:构造时不自动加锁
    std::unique_lock<std::mutex> lock(mtx, std::defer_lock);
    
    // 手动加锁(也可以用try_lock()尝试加锁)
    lock.lock();
    
    // 执行临界区代码
    
    lock.unlock(); // 可以手动提前解锁
} // 析构时若锁还在持有关,则自动解锁

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值