博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux内核 同步
阅读量:5059 次
发布时间:2019-06-12

本文共 1178 字,大约阅读时间需要 3 分钟。

linux本身实现了集中锁机制,各种锁机制之间的差别是,当锁已经被其他线程持有的时候,一些锁使用自旋的方式来等待,另外一些锁会当当前线程改变为睡眠状态然后等待被唤醒。

锁的争用

如果一个锁处于高度争用状态,那么这个锁会成为系统的瓶颈,严重降低系统性能。

伸缩性

作者在树上说是扩展性,或者翻译的问题,我理解为伸缩性更加贴切。把锁的粒度(在什么层面建立锁)细化,可以提供系统的伸缩性,也就是说增加处理器或者内存带来的性能提升更高

原子操作

linux原子操作包含对int和bit两种的原子操作。操作依赖于底层处理器对原子操作的支持。针对bit和int,基本现在大部分处理器都是支持这些常见的原子操作的:

  • 原子的读取和设置数值
  • 原子的加i并返回结果

自旋锁

我的理解:自旋锁应该是通过不断的CAS机器指令来实现的。

自旋锁的作用:适用于不会短时间持有的锁。

因为使用睡眠锁,将会导致两次上下文切换(一次切换出去,一次切换进来),如果锁的持有时间很短,上下文切换带来的浪费还不如使用自旋锁。

信号量

linux中的信号量是一种睡眠锁。

如果一个任务视图获取一个被其他任务持有的睡眠锁,那么这个锁将会被推进等待队列,然后让其睡眠。当持有的信号量被释放后,处于等待队列的任务将被唤醒,

计数信号量和二值信号量

二值信号量就是计数为2的信号量。可以理解为二值信号量就是普通的互斥睡眠锁(相对应与自旋锁)。

信号量的实现:

信号量内部维护一个原子int类型,初始化的时候将这个int类型设置为信号量的计数值。如5。

信号量支持P(),V()操作。P和V是发明信号量的荷兰人的命名。linux中一般叫做down和up。

down就是加锁操作:也就是对原子变量执行--操作并返回结果的操作,如果返回结果<0,那么证明信号量不可用,将当前线程压入这个锁的等待队列。

up也就是释放锁的操作:也就是对原子变量执行++的操作,然后唤醒等待队列中一个或者多个等待的线程。

互斥体

实际上,二值信号量就可以作为互斥的睡眠锁,但是信号量的实现逻辑还不够简单,所以针对这种二值的互斥睡眠锁,linux又发明了互斥体。互斥体的基本原理和二值信号量一致,就是多了一些优化,这里不再赘述。

顺序和屏障

linux提供了三种内存屏障:

rmb():读屏障,不会发生跨越rmb()的载入(读)操作重排序。

wmb():写屏障,不会发生跨越wmb()的写操作重排序。

mb():读写屏障,不会发生跨越mb()的读写操作的重排序。

如下:

a=1;

b=2;

rmb();

c=3;

由于rmb()在存在,所以前两句代码不会发生在后一句代码之后。但是不能保证前两句代码发生重排序。

 

转载于:https://www.cnblogs.com/xiaolang8762400/p/7418786.html

你可能感兴趣的文章
关于js sort排序方法
查看>>
JAVA面试常见问题之Redis篇
查看>>
javascript:二叉搜索树 实现
查看>>
网络爬虫Heritrix源码分析(一) 包介绍
查看>>
__int128的实现
查看>>
Problem - 1118B - Codeforces(Tanya and Candies)
查看>>
jdk1.8 api 下载
查看>>
svn 图标不显示
查看>>
getElement的几中属性介绍
查看>>
iOS 使用Quartz 2D画虚线 【转】
查看>>
平面最接近点对
查看>>
HTML列表,表格与媒体元素
查看>>
PHP、Java、Python、C、C++ 这几种编程语言都各有什么特点或优点?
查看>>
雨林木风 GHOST_XP SP3 快速装机版YN12.08
查看>>
linux基础-命令
查看>>
java对象的深浅克隆
查看>>
Hadoop流程---从tpch到hive
查看>>
数据结构3——浅谈zkw线段树
查看>>
Introduction to my galaxy engine 2: Depth of field
查看>>
V2019 Super DSP3 Odometer Correction Vehicle List
查看>>