Linux内核常见的几种同步手段
Posted 四季帆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux内核常见的几种同步手段相关的知识,希望对你有一定的参考价值。
1.原子操作
原子操作在执行的时候,不可能被拆分成几条原子操作,Linux内核通过提供 atomic_t类型封装了一系列原子操作。
2.优化和内存屏障
在指令之间插入一道屏障,两句屏障指令之间的指令不会因为优化而重排。
编译器优化重排举例:
//优化前
int x = 1;
int y = 2;
int a1 = x * 1;
int b1 = y * 1;
int a2 = x * 2;
int b2 = y * 2;
//优化后,CPU只需要读一次x和y的值,不需要反复读取寄存器来交替x和y值。
int x = 1;
int y = 2;
int a1 = x * 1;
int a2 = x * 2;
int b1 = y * 1;
int b2 = y * 2;
3.自旋锁
它锁住的是一块临界区,进入临界区时需要先获取自旋锁,在离开临界区时需要释放自旋锁。如果有进程已经获取了自旋锁,但是还没有释放,那么其它想要获取自旋锁的进程就得等(而且不能让出CPU,需要一直占着CPU)
4.读写自旋锁(和RCU锁有点像)
这种锁允许多个进程同时对同一数据结构进行读操作,但不允许多个进程同时对同一数据结构进行写操作。读的过程中不允许写,写的过程中不允许读。
5.信号量
信号量和自旋锁类似,也是为了控制进程进入临界区,但是信号量和自旋锁的最大区别是:
获取自旋锁的过程,不会主动调用schedule()进行进程切换,而是占着CPU,拼命的自旋,类似于while耗时操作;
信号量中存在一个进程等待队列,为获取锁的进程将挂接到该队列中,然后主动调用schedule()切换进程,让出CPU。
6. RCU锁
自旋锁、读写锁的使用非常广泛,但是它们使用了原子操作指令,它需要原子地访问内存,因此这种锁的开销对CPU的速度而言很大,一些锁在多CPU情况下,由于加锁的频度变高,性能反倒比一个CPU时差;
RCU锁机制的使用范围比较窄,它只适用于读多写少的情况,如网络路由表的查询更新、设备状态表的维护、数据结构的延迟释放以及多径I/O设备的维护等。
6.1 RCU(Read Copy Update)原理
读(Read):读者不需要获得任何锁就可以访问RCU保护的临界区;
拷贝(Copy):写者在访问临界区时,写者“自己”将先拷贝一个临界区副本,然后对副本进行修改;
更新(Update):RCU机制将在适当时机使用一个回调函数把指向原来临界区的指针重新指向新的被修改的临界区,锁机制中的垃圾收集器负责回调函数的调用。(时机:所有引用该共享临界区的CPU都退出对临界区的操作。即没有CPU再去操作这段被RCU保护的临界区后,这段临界区即可回收了,此时回调函数即被调用)
以上是关于Linux内核常见的几种同步手段的主要内容,如果未能解决你的问题,请参考以下文章