Lunatic: An Erlang-inspired runtime for WebAssembly19 days agohttps://lunatic.solutions/Lunatic是一个受Erlang启发的开源WebAssembly运行时环境。它提供了隔离的轻量级进程,以实现高并发性和容错能力。特性包括通过JIT编译Wasm实现高性能、通过能力限制确保安全性以及分布式集群支持。应用程序可跨架构和操作系统移植,一次编译为WebAssembly即可。监督树机制支持对故障进程的监控和恢复。
FoundationDB's Flow – Bringing Actor-Based Concurrency to C++1119 days agohttps://apple.github.io/foundationdb/flow.htmlFlow 是一种为 C++11 引入基于 actor 并发模型的编程语言,由 FoundationDB 开发,旨在满足高性能、可扩展性和可靠性的需求。它利用 actors、futures、promises 以及如 wait()、ACTOR、state 和 choose...when 等关键字来实现异步消息传递和确定性模拟。Flow 代码被预处理为 C++11,但需要注意本地变量在 wait() 调用后不会保留,同时状态变量和 IDE 支持需要特殊处理。
C++ Details of Asymmetric Fences18 days agohttps://nekrozqliphort.github.io/posts/membarrier/非对称线程栅栏通过将繁重的同步开销从常见路径转移到不频繁的慢速路径来优化并发,在快速路径上使用轻量级编译器屏障,在慢速路径上使用更强的栅栏。轻量级栅栏(asymmetric_thread_fence_light)被实现为编译器屏障(例如:asm volatile("" : : : "memory")),防止编译器重排序但不阻止硬件重排序。在Linux上,重量级栅栏(asymmetric_thread_fence_heavy)使用membarrier()系统调用,该系统调用通过发出处理器间中断(IPIs)来强制执行跨核心的内存排序,涉及在发送IPI前后使用smp_mb()屏障。C++标准通过将非对称栅栏(P1202R5)纳入内存模型来将其正式化,其中规则影响了memory_order_seq_cst操作的单次全序S,并要求谨慎处理以避免传递性问题。实现细节包括在单核或单内存管理(mm)场景中对membarrier()的快速路径优化、特定架构的smp_mb()实现,以及对数据竞争和happens-before关系的考量。
Go-Flavored Concurrency in C11 days agohttps://antonz.org/concurrency-in-c/Go 的并发模型因其轻量级的 goroutine、通道以及高效的运行时调度器而广受欢迎,但在 C 语言中仅使用 POSIX 线程来复现该模型时,需要做出一些权衡。Solod(So)基于 pthread 原语实现了一个并发栈:sync.Mutex 和 sync.Cond 包装了 pthread_mutex_t 和 pthread_cond_t,提供了基本的同步机制。So 中的原子操作直接映射到 C 的 __atomic 内置函数,在加载、存储和比较交换操作上与 Go 的性能相当,且无需 pthread 的开销。So 的 conc.Pool 使用固定数量的工作线程和一个共享任务队列,通过互斥锁和条件变量构建,适用于粗粒度工作负载,但不适用于像 goroutine 那样数千个阻塞任务的情况。So 中的通道(conc.Chan[T])支持缓冲和无缓冲模式,使用互斥锁和条件变量进行同步,在池化任务方面性能接近 Go,但在细粒度任务传递方面由于内核唤醒开销而较慢。基准测试显示,So 基于 pthread 的并发实现在无竞争锁和原子操作方面具有竞争力,但当线程阻塞时,条件变量和通道的性能显著下降,无缓冲通道传输可能慢达 23 倍。设计决策包括使用 pthread 而非纤程以简化实现,将并发功能保留在标准库中以支持显式分配和灵活性,并为通道操作提供超时机制而非 select 语句。该方法在粗粒度工作负载下提供了简单性且性能接近 Go,但由于内核线程管理开销,无法在细粒度并发方面匹配 Go 的效率。
Solving Santa Claus Puzzle9 days agohttps://wyounas.github.io/puzzles/concurrency/2026/01/10/how-to-help-santa-claus...本文探讨了如何使用SPIN模型检查器和Promela解决圣诞老人并发难题。关键约束包括:圣诞老人不能组队;驯鹿等待时优先于精灵;以及完整的队伍(9只驯鹿或3个精灵)必须一同参与。分析了三种失败场景:未等所有驯鹿准备就绪即出发送礼、同时进行送礼和咨询、以及在有驯鹿等待的情况下仍咨询精灵。一个正确的模型引入了用于组队的房间(独立进程),圣诞老人需等待“队伍就绪”信号,以确保正确的同步和优先级。使用SPIN中的线性时序逻辑(LTL)验证了安全性和活性属性(例如互斥、完整队伍参与、进展性)。该解决方案被转换为Go语言的实现,突显了模型检查在发现微妙并发错误方面的教育价值。
Concurrent JavaScript: It can work (2017)6 days agohttps://webkit.org/blog/7846/concurrent-javascript-it-can-work/SharedArrayBuffer 支持 JavaScript 中的并发访问,实现了多线程编程的能力。一个稻草人 API 提案建议为 JavaScript 添加线程、锁、条件变量和线程局部变量,以实现完整的并发支持。WebKit 的实现采用了分段蝴蝶结构以实现无等待操作,并通过转换线程局部性推断来最小化开销。性能目标包括非并发代码零性能倒退、线性可扩展性以及合理的内存模型语义。并发与 DOM 的交互通过限制对仅主线程可访问对象的访问来实现,同时允许对全局属性进行有限的并发访问。所提议的方案依赖于 64 位系统,并旨在使大多数属性访问的开销保持最小。
The Tokio/Rayon Trap and Why Async/Await Fails Concurrency5 days agohttps://pmbanugo.me/blog/why-async-await-complect-concurrencyAsync/await 通过让异步代码看起来像同步代码来简化其编写,但隐藏了调度和控制流中的复杂性,将负担转移给了开发者。Async/await 中将异步和并发混为一谈可能导致生产问题,例如 CPU 密集型任务阻塞协作运行时引起的延迟激增。开发者必须手动将 I/O 和计算任务分离到不同的运行时(如 Tokio 和 Rayon)中,充当“人工调度器”,这削弱了该抽象所承诺的优势。Async/await 运行时通常默认采用无界容量,导致在流量激增期间,由于任务不受控制地生成和排队,引发内存不足崩溃。旨在实现公平性的工作窃取调度器可能会通过破坏 CPU 缓存局部性并引发争用而降低吞吐量,这在 Erlang BEAM 等大型系统中已得到印证。Tina 项目被引入作为一种基于状态机的替代并发框架,其特点包括每核一线程的设计、严格的边界以及用于可预测性的确定性模拟测试。
Notes on structured concurrency, or: Go statement considered harmful5 days agohttps://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-consider...并发 API 传统上使用 go 语句(线程生成、回调、future)来允许后台任务独立运行,类似于控制流中的 goto 语句。Go 语句破坏了抽象,使得函数不再是黑盒(它们可以在调用者不知情的情况下生成任务),扰乱了自动资源清理,并阻碍了正确的错误传播。Trio 引入了托儿所(nursery)作为结构化替代方案,其中任务在托儿所块内启动,父任务在退出前等待所有子任务完成,确保控制流遵循‘黑盒’规则。托儿所保留了函数抽象,支持动态任务生成,允许显式传递托儿所对象以提供灵活性,支持自定义类似托儿所的类型,并集成了自动错误传播和取消功能。移除 go 语句使得 Python 能够实现可靠取消和适当的 Control-C 处理等新功能,托儿所鼓励更清晰、更健壮的并发编程,正如 Trio 中简化的实现(如 Happy Eyeballs)所展示的那样。