2025年条件变量 互斥锁(互斥锁和条件变量机制的工作流程)

条件变量 互斥锁(互斥锁和条件变量机制的工作流程)postgresql 的架构是基于多进程的 进程之间往往存在着数据共享 比如缓存读写 这时 postgresql 需要提高一种锁机制来支持并发访问 但是 linux 只实现了线程间的读写锁 所以 postgresql 自己实现进程间的读写锁 它主要利用了信号量和自旋锁来实现 每个进程都对应一个独立 实例 它包含了多个成员 下面只列出与锁相关的 实例存储在进程共享内存里

大家好,我是讯享网,很高兴认识大家。



postgresql 的架构是基于多进程的,进程之间往往存在着数据共享,比如缓存读写。这时 postgresql 需要提高一种锁机制来支持并发访问,但是 linux 只实现了线程间的读写锁,所以 postgresql 自己实现进程间的读写锁,它主要利用了信号量和自旋锁来实现。

每个进程都对应一个独立  实例,它包含了多个成员,下面只列出与锁相关的

 实例存储在进程共享内存里,在创建进程时会被初始化。这里需要提醒下,信号量 sem 的初始值为0,属于无名信号量。

结构体表示读写锁,结构如下:

需要介绍下 state 字段的标记位

加锁原理

函数负责整个加过程,这里将过程分为下面四步:

从上面可以看出来,这里采用的是非公平锁机制,也就是谁的速度快,谁就能获取到锁,没有先来先获取的顺序。

尝试通过 CAS 操作,设置或标记位。来获取锁。使用到的 CAS 操作函数如下:


讯享网

当尝试获取读锁时,只需要检查标记位。如果为零,就认为成功获取。

对于队列的操作,都需要使用自旋锁来设置 标记位,才有权利操作队列。当设置成功后,会将自身添加到等待列表,然后更新自身进程对应实例的  和  成员,最后释放锁,清除标记位。

当加入到队列后,还需要更新标记位,表示有进程在等待。

postgresql 是多进程架构的,进程之间使用信号量来同步。当进程获取锁失败时,会将自身添加到等待队列里,然后通过信号量进行阻塞,直到被别的进程唤醒。对于 postgresql 的每个进程都有一个信号量,由实例的 sem 成员表示。sem 信号量的初始值为0,它的数值代表着满足的条件数。

因为这个 sem 信号量会有多个用途,所以每次唤醒操作,并不一定是期望的条件发生,所以进程在被唤醒之后,需要一次条件检查。如果是因为其他条件唤醒,还需要记录被唤醒次数,在事后需要将执行相应次数的唤醒操作。

假设下面有一个进程A对应信号量A,它会被用于两个方面,条件A和条件B。

进程A正在阻塞条件A,此时进程B因为条件B唤醒了进程A。但进程A发现并不是期望的条件所唤醒的,所以它会继续阻塞,直到满足条件A被唤醒,最后进程A还会执行一次唤醒操作。

当获取到锁之后,如果自身在等待队列中,需要将其删除掉。如果之后队列为空,需要清除标记位,当然这些操作都需要获取锁。

下面展示了的源码,描述了整个加锁过程

释放锁

函数负责释放锁,定义如下:

释放锁分为下列步骤:

下面列举了两种情况来阐述锁释放的原理:

在取出进程之后,会清除标记位。如果检查到队列为空,还会清除标记位。

lwlock 在 postgresql 中使用的场景非常多,为了更好管理这些 lwlock,postgresql 按照用途将它们分类,大体分为三个部分:

小讯
上一篇 2025-05-03 13:55
下一篇 2025-05-03 11:12

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/201768.html