并发哈希表:分段锁、桶锁、协作扩容与分裂有序表
对照 JDK 7/25 的 ConcurrentHashMap、NonBlockingHashMap、Linux rhashtable 与 Go sync.Map 的源码,说明并发哈希表真正难的是扩容;实测桶长分布、扩容克隆比例与树化条件,并给出通过 TSan 的分裂有序表实现。
Linux 内核、存储与网络、可观测性、系统架构与大模型基础设施的工程笔记:机制拆解、踩坑复盘与可核对证据,少空谈。
共 20 篇文章 · 返回首页
对照 JDK 7/25 的 ConcurrentHashMap、NonBlockingHashMap、Linux rhashtable 与 Go sync.Map 的源码,说明并发哈希表真正难的是扩容;实测桶长分布、扩容克隆比例与树化条件,并给出通过 TSan 的分裂有序表实现。
对照 Go 1.25、crossbeam-channel、DPDK v25.11 源码,拆解有界 channel 的一把锁、逐槽 stamp、两阶段预留三种环与直接交接、通知重试两种唤醒;实测线程停顿、丢失唤醒、公平性与 TSan 报告。
从宽限期保证的形式陈述出发,对照 liburcu 0.15.7 与 Linux v6.12 源码,说明读侧省掉的 StoreLoad 栅栏由谁补上、'读侧零开销'在哪些配置下成立;实测读侧开销、宽限期延迟、membarrier IPI 转嫁给读者的代价和一个缺栅栏的变异体。
按 Michael(TPDS 2004)的条件拆解 hazard pointers:发布后为何要复读、StoreLoad 栅栏防哪种重排、未回收节点的上界从哪来;实测两个变异体、x86 store buffering 和每个指针的开销,对照 Folly、C++26 与乐观遍历之争。
从 Fraser(2004)的三个 limbo list 出发,推导 EBR 为什么要等两个纪元、垃圾该打哪个纪元的标签;对照 crossbeam-epoch 0.9.18 源码,实测两个变异体、pin 的指令选择、每节点开销、回收速率上限,以及一个被抢占或睡住的读者让垃圾涨到多少。
钉 etcd v3.5.33 Txn 的 compareToPath、MOD/CREATE/VERSION 比较与写 Txn 的 Raft 单槽 apply,并对照 Jepsen 3.4.3 的 strict-serializable 与 Lease 锁不安全子集。
拆穿高星「无锁」库:隐藏 mutex、被滥用的 memory_order_relaxed,以及 CAS 重试循环的阻塞本质;附 x86 vs ARM 差异。
一个在 x86 上跑了两年的内核模块,迁移到 ARM 后开始随机丢数据。三天的调试过程教会了我 smp_wmb() 的真正含义。附 Linux 内核屏障 API 完整分类与 x86/ARM 编译产物对比。
钉住官方 File Locking And Concurrency 文档定义的 UNLOCKED/SHARED/RESERVED/PENDING/EXCLUSIVE 五态锁阶梯:谁能与谁共存、PENDING 如何防写者饿死、Pager 为何只跟踪四态;用本机 3.53.2 真实双连接冲突实验验证,shared cache 与 WAL 差异只点边界,留给第 8、10 篇。
拆解 PostgreSQL 锁管理器的完整架构:SpinLock 自旋锁的硬件原语与使用边界、LWLock 从 PG 9.4 前到 PG 16 LWLockWaitListLock 的三代演进、Heavyweight Lock 的 LockAcquire() 完整路径和锁表结构、死锁检测 DeadLockCheck() 的等待图 DFS 算法、行级锁 FOR UPDATE/FOR SHARE/FOR KEY SHARE 的 t_infomask 实现,以及用 pg_locks 和 pg_blocking_pids() 追踪生产锁等待链的诊断方法。
BPF 程序在内核上下文中并发执行——同一程序可能在多个 CPU 同时运行。本文讲清 BPF 环境下的内存模型(BPF_ATOMIC 指令的语义)、bpf_spin_lock 的实现限制、RCU 保护的 map 读取、per-CPU map 的免锁读写,以及中断上下文与进程上下文的执行语义差异。
单机吞吐量的理论上限取决于硬件并行度和软件调度效率。本文从 Amdahl 定律出发,分析批处理的最优批大小、流水线的级间平衡、Nagle 算法与 TCP_CORK 的工程权衡,给出数据库批量写入、Kafka 生产者调优、网络写合并等真实场景的优化路径。
数据库要把数据存到磁盘上,又要以尽可能少的磁盘 I/O 把数据找回来。这个矛盾催生了一系列面向磁盘的索引结构(Disk-oriented Index),其中最成功的就是 B-Tree 家族。从 1970 年 Rudolf Bayer 和 Edward McCreight 在波音科学研究实验室提出 B-Tree 起,这个…
组装完整 LSM-Tree 存储引擎:DB 接口(Open/Put/Get/Delete/Iterator/Snapshot)、单写多读并发控制、启动恢复,然后用 Rust 重写核心模块,记录 5 个编译器不让我过的故事,最后三方 benchmark 对比。从零写一个 LSM-Tree 存储引擎系列第 5 篇。
Golang 线程池实现:高效并发编程,goroutine 池管理与性能优化
从源码级别拆解 Go runtime 的 GMP 调度器:G/M/P 结构体、schedule() 调度循环、work stealing、协作式到异步抢占的演进、netpoller 与 syscall 处理,以及与 Linux CFS 调度器的正面对比。
Linux 内核 ACCESS_ONCE/READ_ONCE/WRITE_ONCE 宏详解:并发编程与内存访问
正确的无锁数据结构可以写出来。但代价比你想象的大。CAS 循环、ABA 问题、内存回收、x86 和 ARM 的行为差异——这篇从一行 compare_exchange 开始,到一个完整的无锁哈希表结束。
从 Future::poll 到 work-stealing 调度器,从 Waker vtable 到 mio/epoll I/O 驱动,再到层级时间轮——一层一层拆开 tokio 约 40000 行代码的运行时内核,看看你每写一个 .await 背后到底发生了什么。
不是'谁快'——而是'什么维度上谁更合适'。在延迟、吞吐量、内存占用、编译速度、并发模型五个维度上正面对比,用同一个任务的三种实现说话。