Linux中的锁机制

今天面试被虐成翔了,先是所做项目部分的数据结构设计解释的不清不楚,然后关于内核的部分,原本自以为知识点都掌握的差不多,真到临场才发现,看书理解是一回事,要给别人讲清楚那又是另外一回事,还好面试官和气,能够顺利进入二面。没办法,多么痛的领悟必须转为多么重的动力。从锁机制开始,这个东西真的很高深,今天果断就被面试官灭了一回。书上的锁知识都是基本,实践做项目才能发现问题以及解决办法,我还没到这个境界,但至少需要把书中基本的搞清楚,以后的面试要能清楚的解释出来。

关键词解释:

执行线程:指任何正在执行的代码实例,比如,一个在内核执行的进程、一个中断处理程序或一个内核线程,本文中简称线程

为什么需要加锁?

       多线程并发访问同一个共享资源,可能造成各线程之间相互覆盖共享数据,造成被访问数据处于不一致状态。为了避免这种情况,需要由我们保证访问和操作资源的代码必须原子地执行。对于单个变量,内核提供了原子操作,而对于复杂的数据结构时,比如链表,就需要提供锁机制,然后加锁来提供保护。

各种锁机制之间区别在于当锁已经被其他线程持有,其不可用时的行为表现----一些锁被争用时会简单地执行忙等待,而另外一些则会使当前任务睡眠直到锁可用为止

死锁

       死锁是引入加锁机制后可能产生的安全隐患。如果面试官问了死锁产生的原因,请不要再简单说是为了竞争资源云云,举实例才是王道,真正有料的面试官是不跟你玩弄文字的,这回面试我是深有体会,废话不多说。

       死锁产生条件:要有一个或多个执行线程和一个或多个资源,每个线程都在等待其中的一个资源,但所有资源又均已被占用。所有线程都在相互等待,但它们永远不会释放已经占有的资源。于是任何线程无法继续,死锁发生。

       死锁常见实例:

       1,自死锁

        一个线程试图去获得一个自己已经持有的锁。eg. 1, 连续加两把写锁;2,先加读锁再加写锁;3,Linux中,连续加两把自旋锁;

       2,N线程N把锁死锁

        每个线程都持有一把其他进程需要得到的锁,于是所有线程阻塞等待它们希望得到的锁重新可用。eg. 两线程两把锁,即ABBA死锁。图况如下:

      

       3,双重请求死锁

         eg. 持有自旋锁的线程收到中断,被中断程序抢占,然后在中断程序里面争用已持有的自旋锁。

       ......(待补充)

锁类型

       先明确一个概念,临界区。所谓临界区,就是访问和操作共享数据的代码段。这个代码段的跨度甚至可以是多个函数。例如,先从一个数据结构中移出数据,对其进行格式转换和解析,最后再把它加入到另一个数据结构中。整个执行过程必须是原子的,在数据被更新完毕前,不能有其他代码读取这些数据。这种情况下,便会使用加锁机制。

自旋锁:

       Linux中最常见的锁,最多只能被一个可执行线程持有。自旋锁的特点:如果发生争用,争用线程会一直进行忙循环----旋转----等待锁重新可用(特别浪费处理器时间)。因此自旋锁不应长时间持用。在任意时刻,自旋锁都可以防止多于一个的执行线程同时进入临界区。

      读--写自旋锁,一种特殊的自旋锁,锁的用途明确分为读取和写入两个场景。多个读者可以安全地获取同一把锁,而写锁只能被一个任务持有。

      如果加锁时间不长并且代码不会睡眠(比如中断处理程序),自旋锁是最佳选择。而持有自旋锁的时间最好小于两次上下文切换的时间。原因:另外一种加锁表现是争用锁时,让请求线程投入睡眠,直到锁重新可用时再唤醒。虽然处理器此时不必循环等待,可以执行其他代码,但是,这里这样做就会有两次明显上下文切换,即请求线程换入换出。

信号量:

互斥体:

RCU机制:

       RCU(read-copy-update)是一种新的同步机制,在内核版本2.5开发期间添加。RCU性能很好,对内存有一定开销,但大多数情况下可以忽略。使用RCU机制的限制:

      1,对共享资源的访问在大部分时间只读,写访问相对较少;

      2,RCU保护的代码范围内,内核不能进入睡眠状态,与信号量相同;

      3,受保护资源必须通过指针访问;

      RCU原理:该机制记录指向共享数据结构指针的所有使用者。在该数据结构将要改变时,首先创建一个副本,在副本中进行修改。当所有进行读访问的使用者结束对旧副本访问之后,指针替换为新的、修改完成后的指针。此机制允许读写并发进行!

      RCU能保护读访问不受写访问的干扰,但不对写访问之间的相互干扰提供保护!

本文详情请参考《Linux内核设计与实现》、《深入Linux内核架构》
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值