内核锁浅析

内核锁浅析

1. 临界区

临界区:访问和操作共享数据的代码段,在多线程并发访问同一资源时,有可能会导致数据读写异常,多线程之间相互竞争,并且问题不容易复现,调试困难,所以需要引入临界区保证代码段是原子性的,要么执行,要么不执行,不容许执行过程中被打断。

2. 锁

在许多cpu体系结构中,提供了简单的原子操作,例如:算数运算中的自增自减等原子操作。但是在体系结构中没有特定指令对 不定长度 的临界区进行保护。因此就引入了锁机制,它如同一把门锁,门后房间可以想象为一个临界区,当一个线程进入房间后,它会锁住房间门,当他对共享数据操作结束后,就会走出房间,打开门锁。

  • 锁需要保护什么

    锁需要保证数据的安全,以及一些时序正确(针对硬件),如果其他执行线程可以访问同一数据,那么就需要给数据加上某种形式的锁,是针对数据或时序加锁而不是给代码加锁。在内核中几乎所有的内核全局变量和共享数据都需要某种形式的锁(同步)方法。

    在编写内核代码时,需要考虑到以下问题

    • 这个数据是不是全局的?除当前线程外,其他线程能不能访问它?
    • 这个数据会不会在进程上下文和中断上下文中共享?它是不是要在两个不同的中断处理程序中共享?
    • 进程在访问数据时可不可能被抢占?被调度的新程序会不会访问同一数据
    • 当前进程是不是会睡眠(阻塞)在某些资源上,如果是,它会让共享数据处于何种状态?
    • 怎么防止数据失控?
    • 如果这个函数又在另一个处理器被调度将会发生什么(重入性)
    • 如何确保代码原理并发威胁
  • 死锁

    死锁产生:要有一个或多个执行线程和一个或多个资源,每个线程都在等待其中的一个资源,但所有资源都已经得占用,所有线程都相互等待,但它们永远不会释放已经占有的资源,任何线程都无法继续,意味着死锁发生。
    这里写图片描述

    上图为死锁简单图示,线程A持有锁X,线程B持有锁Y,同时线程A请求锁Y,线程B请求锁X,这样就造成死锁。

    例如:四路交通堵塞问题,如果每一个停止的车都决心等待其他车启动后再启动,那么没有一辆车能启动,造成交通死锁。
    这里写图片描述

    造成死锁的四个必要条件
    这里写图片描述

  • 锁粒度问题

    锁的粒度问题,主要是小型SMP和大型SMP(服务器)之间的区别。加锁粒度用来描述加锁保护的数据规模,例如:大粒度锁保护一个数据结构,小粒度锁保护这个数据结构中的一块数据。在集群处理器中,大粒度锁可能会造成性能瓶颈,例如,当各处理器需要频繁访问一个链表时,如果只对这个链表单独使用一个锁,就会出现性能瓶颈。在当细粒度变小后,对每个结点加锁,多处理器只有在访问同一结点时才争用一个锁。但细粒度变小后,在小型SMP中会造成什么后果?多余的锁造成系统开销增大,造成系统性能浪费。锁争用严重时,加锁过粗,很容易造成性能瓶颈;锁争用不明显时,加锁过细会加大体统开销。

​ ^主要参考《LINUX内核设计与实现》^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值