天天看点

linux下的同步机制的实现前言参考资料TODO

前言

学习自用,有错麻烦提一下,,现在还没写完,,以后再慢慢补充

同步机制先大概列出这几种

mutex

互斥锁的实现总结;实际上就是一把锁(自旋锁)维护了一个等待队列和一个引用计数器,当获取锁之前,先对引用计数器减1操作,如果为非负,则可以获取锁进入临界区。否则将该任务加入该等待队列上。当mutex解锁的时候,判断队列是否为空,不为空则唤醒队列的任务

详细:原子计数一开始初始化为1,mutex.lock()的时候先把原子计数减一,若为0则可获取,为负数则不可获取,采取一系列操作(以上这些操作减一并判断这两个动作应该是原子操作)

用spinlock保护等待队列,把当前进程/线程加入到等待队列,期间也会检查下原子计数是否可以获得mutex,还不行就spinlock.unlock()并运行schedule()来调度到其他线程,等其他线程调度回来后再重新运行以上任务

spinlock

• 用在哪:

比如说memory descritpor的保护,许多内核数据结构都用这个和semaphore;

比如中断处理函数只能用这个不调度的spinlock,还有TODO

• 实现原理:

用普通的unsigned int lock实现,自旋锁如果可以获取,unsigned intlock值减一为0就直接进入临界区,并锁住总线不让其他CPU访问(这一步不太懂),如果不可以lock值为负数就不断循环检测,直到锁释放;解锁操作则是直接把unsigned int lock重新置为1

更具体见参考资料2

原子操作

• 实现原理:一般是特定的指令,不支持的CPU则用关闭中断来实现

• 有atomic_32和(增加运算是啥来着)

• 使用注意:int更快吧,大小也是个问题,

• 种类:有32位的也有64位的atomic64,还有bit的原子操作

读写锁

种类:RW锁和seq_lock

区别是seq_lock是写者优先,RW即我们平时用的读写锁

实现原理:应该不用知道吧

使用场景:TODO

semaphore

• 注意:一般是底层实现,不拿来应用层用

• 使用地方:举个例子,这个在内核中也挺常见的

• 实现原理:也是atmoc来实现的,atomic_t的资源个数 ;进程睡眠队列和等待人数

其他

  1. CV:知道干嘛用的就行了吧,C语言有哪些接口呢,这个也是基于semaphore实现的
  2. BKL:这个好像给遗弃了,好像毕竟是种过渡到细粒度的锁,所以这细粒度的锁是什么呢?
  3. 还有种锁三个字母的是什么?
  4. mutex:最常用的,不用说的,这个要注意不能在interrupt handler中使用,因为它不能够context switch(说是不能够再次调度回来,为什么不能呢),mutex怎么实现的呢(好像是test-and-set,compare-and-swap,fetch-and-add?)

参考资料

  1. https://blog.csdn.net/wdzxl198/article/details/11975627自旋锁更深入的解答
  2. 自学内核的人,锁的实现https://zhuanlan.zhihu.com/p/34697351
  3. 如何实现一个互斥锁,互斥锁的实现原理,https://blog.csdn.net/u011244446/article/details/52574369

TODO

  1. CAP和RCU
  2. linux锁,很全https://www.cnblogs.com/holyxp/p/10111524.html#_label1_9
  3. 这个是RCU的https://blog.csdn.net/zhoutaopower/article/details/86646688
  4. 锁怎么实现? 硬件锁机制,自旋锁CAS,mutex睡眠等待唤醒,rcu锁机制
  5. 如何理解互斥锁、条件锁、读写锁以及自旋锁? - 知乎 https://www.zhihu.com/question/66733477