
内核同步
文章平均质量分 93
jianchi88
这个作者很懒,什么都没留下…
展开
-
Linux中的 mutex [二] —— 乐观自旋机制
本文基于 5.4.86 版本内核mutex可视作是 spinlock 的可睡眠版本,同样是线程无法继续向前执行,但 spinlock 是"spin",导致该 CPU 上无法发生线程切换,而 mutex 是"block"(我们通常翻译成「阻塞」),可以发生线程切换,让所在 CPU 上的其他线程继续执行。阻塞既可以发生在线程试图获取 mutex 时,也可以发生在线程持有 mutex 时。现在的 mutex 机制,要从这几方面纬度理解:optimistic spin 机制osq lock 机制(见前.原创 2022-04-07 16:56:50 · 1205 阅读 · 0 评论 -
Linux中的 mutex [一] ——handoff 机制
mutex可视作是 spinlock 的可睡眠版本,同样是线程无法继续向前执行,但 spinlock 是"spin",导致该 CPU 上无法发生线程切换,而 mutex 是"block"(我们通常翻译成「阻塞」),可以发生线程切换,让所在 CPU 上的其他线程继续执行。阻塞既可以发生在线程试图获取 mutex 时,也可以发生在线程持有 mutex 时。现在的 mutex 机制,要从这几方面纬度理解:optimistic spin 机制osq lock 机制(MCS 锁机制,前面的文章有说)hand原创 2022-03-15 15:41:46 · 2035 阅读 · 0 评论 -
Linux中的锁机制 —— osq lock
osq 数据结构6 /*7 * An MCS like lock especially tailored for optimistic spinning for sleeping8 * lock implementations (mutex, rwsem, etc).9 *10 * Using a single mcs node per CPU is safe because sleeping locks should not be11 * called from inte原创 2022-03-07 15:53:31 · 4801 阅读 · 0 评论 -
Linux中的spinlock机制[四] - qspinlock无代码理解
独占原先的实现方式是arch_spin_lock,使用 ldaxr 和 stxr 指令实现锁变量的修改。这两个指令暗含独占监视器的功能。ldxr 和 stxr 是成对使用的。L = local;G = global对于一个内存地址,没被任何 cpu 访问的话是开放的,任何 cpu 都可以去占有这段地址,只要 cpu执行 ldxr 就会标记此内存已被占有(L)。关键点在 stxr。当 cpu 1 用 stxr 修改了独占的内存,表示该内存使用结束,重新回归开放状态(G),这里的开放所有 cpu 都看原创 2022-02-22 10:04:25 · 1507 阅读 · 0 评论 -
Linux中的spinlock机制[三] - qspinlock
上文说到,MCS lock可以解决在锁的争用比较激烈的场景下,cache line无谓刷新的问题,但它内含一个指针,所以更消耗存储空间,但这个指针又是不可或缺的,因为正是依靠这个指针,持有spinlock的CPU才能找到等待队列中的下一个节点,将spinlock传递给它。本文要介绍的qspinlock,其首要目标就是把原生的MCS lock结构体进行改进,「塞」进4字节的空间里。【MCS Lock的改进 - qspinlock】先来看一下有3个以上的CPU持有或试图获取spinlock时,等待队列的全貌转载 2022-02-17 14:36:49 · 605 阅读 · 0 评论 -
Linux中的spinlock机制[二] - MCS Lock
上文提到,每当一个spinlock的值出现变化时,所有试图获取这个spinlock的CPU都需要读取内存,刷新自己对应的cache line,而最终只有一个CPU可以获得锁,也只有它的刷新才是有意义的。锁的争抢越激烈(试图获取锁的CPU数目越多),无谓的开销也就越大。【第三种实现 - MCS Lock】如果在ticket spinlock的基础上进行一定的修改,让每个CPU不再是等待同一个spinlock变量,而是基于各自不同的per-CPU的变量进行等待,那么每个CPU平时只需要查询自己对应的这个变量转载 2022-02-16 12:01:11 · 1084 阅读 · 0 评论 -
Linux中的spinlock机制[一] - CAS和ticket spinlock
Linu为什么要加锁在SMP系统中,如果仅仅是需要串行地增加一个变量的值,那么使用原子操作的函数(API)就可以了。但现实中更多的场景并不会那么简单,比如需要将一个结构体A中的数据提取出来,然后格式化、解析,再添加到另一个结构体B中,这整个的过程都要求是「原子的」,也就是完成之前,不允许其他的代码来读/写这两个结构体中的任何一个。这时,相对轻量级的原子操作API就无法满足这种应用场景的需求了,我们需要一种更强的同步/互斥机制,那就是软件层面的「锁」的机制。同步锁的「加锁」和「解锁」是放在一段代码的一前转载 2022-02-16 09:49:41 · 588 阅读 · 0 评论