1 个不稳定版本

0.4.3 2022年10月18日

#404 in 并发

Apache-2.0

96KB
2K SLoC

STM

此 crate 包含两种不同的实现,以在 Stronghold 中实现并发。我们实现了两种方法

概述

动机

Stronghold 使用 actix 作为 Actor 框架来管理底层系统中的并发操作。虽然 Actor 系统不是一个坏的选择,因为它抽象了复杂的同步机制,但 actix 明确拥有底层执行器框架的所有权,这使得将 Stronghold 集成到共享环境中变得困难。此外,actix 在单线程事件循环上运行,这使得每个线程的 Actor 隔离变得过时。

基于 TL2 的软件事务内存 (STM)

~在一个基于 STM 的系统中,所有具有可变状态的对象都是事务性的,对象的行为可以通过底层系统透明地使用。这隔离了受保护的内存,防止它在运行时暴露。事务总是安全的;内部冲突会自动回滚并重试,直到事务成功。可变内存上的操作是可组合的。由于只有写操作可以更改对象,因此必须将这些操作传达给其他线程。

最近的工作描述了多种方法,其中我们考虑了阻塞或重试其他事务。这是确保数据一致性的最可行方法。如果事务在所有读取操作验证完成时完成,则将结果提交给实际对象;操作同一对象的线程永远不会看到对此对象所做的更改。

本文描述的STM使用了一种懒加载方法来回滚事务。STM也可以被描述为一种乐观锁方法:在发生冲突之前,对内存的操作被认为是安全的,事务可以安全地回滚并重试。

我们选择了实现STM的TL2版本。您可以在《事务锁定II(2006)》论文中找到实现细节。对TL2所应用的改进和测试在《软件事务内存引擎的测试模式》论文中展示。

当前缺陷

  • 可以被克隆并在线程间共享的变量被分类到枚举SharedValue.
    • 这并不理想,因为我们需要将Stronghold的类型导入此crate才能使用我们的STM实现。
    • 我们尝试使用特例对象进行泛型实现(共享类型需要实现一个特例以在STM中使用),但并不成功。这主要是因为共享变量需要实现Clone: Sized以供STM使用,但由于它们是特例对象,它们还需要实现!Sized。同时实现两者是不兼容的。
  • 这很慢。Stronghold的测试表明,大部分时间单线程比多线程(x10)更快。

读-日志-更新

RLU是一种类似于STM的方法,主要区别在于事务从不回滚,而是被阻塞直到可以提交,产生一致的状态。您可以在《读-日志-更新》论文中找到RLU的实现细节。

当前缺陷

  • 测试中出现了数据竞争和死锁。

特性

[x] - 多个并发读写。 [x] - 锁定免费集成。 [x] - (可选)集成了受保护内存处理。

开放问题 / 待办

  • 功能门控的安全内存。
  • RLU是一个全局上下文,必须从多个线程可变地访问,因为新的上下文可以随时产生。
  • 检查try_lock是否需要返回日志的完整副本,或者是否需要延迟更改。

依赖

~3–4.5MB
~95K SLoC