面试题学习笔记7:C++中的四种锁

线程之间的锁有四种:互斥锁,条件锁,自旋锁和递归锁(不推荐使用)。锁的功能与锁的性能成反比。

互斥锁

互斥锁用于控制多个线程对共享资源互斥访问的一个信号量。可以避免多个线程再某一时刻同时操作一个共享资源。
在某一时刻,只能有一个线程可以获取互斥锁,在释放互斥锁之前其他线程都不能获取该互斥锁。如果其他线程想要获取这个互斥锁,则线程只能以阻塞方式进行等待。
互斥锁是是一种sleep-waiting的锁。假设线程T1获取互斥锁并且正在core1上运行时,此时线程T2也想要获取互斥锁(pthread_mutex_lock),但是由于T1正在使用互斥锁使得T2被阻塞。当T2处于阻塞状态时,T2被放入到等待队列中去,处理器core2会去处理其他任务而不必一直等待(忙等)。也就是说处理器不会因为线程阻塞而空闲着,它去处理其他事务去了。

头文件:
类型:std::mutex
用法:构建std::mutex的实例来创建互斥元,调用成员函数lock()和unlock()来解锁。
例子:

#include<list>
#include<mutex>
std::list<int>some_list;
std::mutex some_mutex;
void add_to_list(int new_value)
{
     std::lock_guard<<std::mutex>guard(some_mutex);
     some_list.push_back(new_value);
}

条件锁

条件锁就是条件变量,某一个线程因为某个条件为满足时可以使用条件变量使改程序处于阻塞状态。条件满足以后,就通过信号量的方式唤醒被该条件阻塞的线程。最常见的是,任务队列为空时,线程池种的线程因为任务队列为空这个条件而处于阻塞状态,任务进入后,就会以信号量的方式来唤醒一个线程来处理任务。
头文件:< condition_variable >
类型:std::condition_variable(只和std::mutex一起工作) 和 std::condition_variable_any(符合类似互斥元的最低标准的任何东西一起工作)。

自旋锁

自旋锁是一种busy-waiting的锁。也就是说,如果T1正在使用自旋锁,而T2也去申请这个自旋锁,此时T2肯定得不到这个自旋锁。与互斥锁相反的是,此时运行T2的处理器core2会一直不断地循环检查锁是否可用(自旋锁请求),直到获取到这个自旋锁为止。
从“自旋锁”的名字也可以看出来,如果一个线程想要获取一个被使用的自旋锁,那么它会一致占用CPU请求这个自旋锁使得CPU不能去做其他的事情,直到获取这个锁为止,这就是“自旋”的含义。
当发生阻塞时,互斥锁可以让CPU去处理其他的任务;而自旋锁让CPU一直不断循环请求获取这个锁。通过两个含义的对比可以我们知道“自旋锁”是比较耗费CPU的。

递归锁

recursive_mutex 类是同步原语,能用于保护共享数据免受从个多线程同时访问。
recursive_mutex 提供排他性递归所有权语义:
调用方线程在从它成功调用 lock 或 try_lock 开始的时期里占有 recursive_mutex 。此时期间,线程可以进行对 lock 或 try_lock 的附加调用。所有权的时期在线程调用 unlock 匹配次数时结束。
线程占有 recursive_mutex 时,若其他所有线程试图要求 recursive_mutex 的所有权,则它们将阻塞(对于调用 lock )或收到 false 返回值(对于调用 try_lock )。
可锁定 recursive_mutex 次数的最大值是未指定的,但抵达该数后,对 lock 的调用将抛出 std::system_error 而对 try_lock 的调用将返回 false 。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值