阅读《Linux内核设计与实现》补充Linux操作系统知识系列(五)之内核同步入门简介

2021/06/02 Operating_System 共 1046 字,约 3 分钟

本篇将会简单的介绍内核的同步入门简介

内核同步的简单概念

临界区

  • 临界区这个词语听起来云里雾里的,但是其实很简单,就是一段代码段,这一段代码段可以访问共享资源
  • 说的这么玄乎,其实我自己有简单的理解,就是将之类比称为被sync锁住的代码段,感觉意思差不多,有的时候我们通过sync锁住一段代码也是为了这段代码可以不被并发执行

内核中需要保护的资源

  • 这个话题说起来有点搞笑,那就是linux内核中能够被并发访问的数据结构、资源基本上都需要被加锁保护,所以我们可以用反向思维,思考到底什么不需要被保护
    1. 只被特定线程访问
    2. 线程自己使用的资源
    3. 局部变量

内核同步方法

原子操作

  • 原子操作非常容易理解,这里我直接引用Java中的一个结构,AtomicInteger,这个结构中的操作就是原子操作,linux内核里面也有类似的(说是类似其实只是感觉很像,这里我是为了自己方便理解)

    image

自旋锁

  • 自旋锁没有什么好说的,和我们平时理解的自旋锁没有什么区别,不过linux内核的自旋锁有一个非常非常坑的特性,那就是不可重入!
  • linux的自旋锁不可以调用递归,因为linux的自旋锁是不可重入的,这就很操蛋,必须很小心的使用 image

读—写自旋锁

  • 读写自旋锁,顾名思义,就是基于自旋锁的读写锁 image

信号量

  • 乍一看这个好像不是什么锁,但是只是这么名字有点奇怪而已,这其实是Linux内核中的一种睡眠锁
  • 顾名思义,这个锁可以让其他未获取锁资源的线程在等待队列中睡眠,直到这个锁资源被释放然后沉睡的线程被唤醒,起来获取锁资源
  • 这个锁就可以类比Java里面的重量级锁
  • 想要沉睡和唤醒一个线程的代价是很高的,所以这个信号量和自旋锁的适用情况和Java中Sync和CAS的适用条件是一致的 image

读—写信号量

  • 没啥好说的,就是基于信号量实现的读写锁

互斥体

  • 信号量比较适合于使用在那些状况复杂,情况未明的场景,对于简单场景不适用(重量大)
  • 为了解决这个问题,人们开发出了互斥体(mutex),这是一个适用于简单场景的睡眠锁
  • 说实话,mutex这个单词在Java的源码中就经常出现,例如在Collections.synchronizedMap()方法里面,被转换成为syncMap的hashmap里面,保证同步的sync锁锁住的就是一个被命名为mutex的obj对象 image

屏障

  • 在linux内核里面,也存在屏障,这里面的屏障被称为barrier
  • linux一共有三种屏障
    1. rmb:读屏障
    2. wmb:写屏障
    3. mb:混合屏障

小结

  • 总而言之,以上的同步方法都是为了保证内核中的代码可以安全的执行,和Java中的锁机制有异曲同工之妙

文档信息

Search

    Table of Contents