#object-pool #pool #no-alloc #non-blocking #embedded #no-std

no-std lock_pool

强大、高效、高性能、异步对象池

2 个不稳定版本

0.2.0 2024年3月1日
0.1.0 2024年2月22日

#525 in 并发

Download history 13/week @ 2024-03-27 27/week @ 2024-04-03 2/week @ 2024-05-22

每月下载量 73 次
用于 swimming

MIT/Apache 许可证

38KB
551

LockPool

CI

LockPool 是专为满足高性能、实时系统的严格要求而设计的,它是一个高吞吐量、公平且线程安全的 Rust 异步对象池,在效率和低延迟至关重要的环境中提供了无与伦比的性能。其架构专门针对在各种环境中无缝运行而量身定制,从 bare-metal 系统(如 seL4)的受限领域到 Linux 等操作系统的广泛生态系统,不依赖任何关于底层异步运行时的假设。通过利用核心 futures 和 wakers,LockPool 能够轻松集成到任何异步生态系统中,保持运行时无关性,确保广泛的适用性。

LockPool 以无_std 和无_alloc 限制为核心,是嵌入式系统和其他内存受限环境(在这种环境中动态内存分配可能不受欢迎或不可用)的理想解决方案。这种对简约和效率的关注确保了 LockPool 轻量级且灵活,适用于各种用例。

工作原理

LockPool 与其他仅仅利用同步机制的库不同,它将同步的原则融入到其架构中。在核心,池由轻量级互斥锁组成,单独的互斥锁只提供基本的互斥保证。然而,LockPool 的真正创新在于其对这些互斥锁的复杂管理,这协调了资源访问。

这种协调是双方面的

  1. 竞争管理:与依赖于复杂锁定方案的传统方法不同,LockPool 采用了一种直接且高效的方法来管理对资源的访问。池中的每个互斥锁以最小的开销运行,允许线程竞争访问,避免了锁竞争的常见陷阱。这在高性能和实时系统中尤为重要,因为最小化延迟至关重要。

  2. 公平性和效率:通过无锁队列来管理等待对象的线程,确保了公平性。这个队列防止了优先级反转,并确保等待线程能够及时且可预测地获得访问权。通过将等待机制与互斥锁解耦,LockPool 在资源分配中实现了公平性和效率的水平,这在传统的锁定策略中很少见。

本质上,LockPool 将同步的概念从潜在的瓶颈转变为一种动态、高效且公平的资源管理系统。它能够将竞争分布到对象上,并管理等待的线程,而不会引入优先级反转或不必要的开销,这使得它成为性能和可靠性不可妥协的应用程序的典范解决方案。

特性

  • 高竞争下的高性能:在高度竞争的场景中表现出色,LockPool 为池化对象提供高效的访问,显著优于传统的锁定方法。
  • 公平性和可预测性:通过无锁队列和具有竞争感知的池设计确保公平访问,对于实时系统来说非常可靠。
  • 环境无关和运行时无关:由于仅依赖核心的 futures 和 wakers,它在各种平台和异步运行时之间兼容。
  • 无_std & 无分配兼容性:非常适合内存约束严格的系统,强调效率和资源节约。
  • 线程安全:提供对池对象的线程安全并发访问,确保数据完整性和系统稳定性。

示例

use lock_pool::{LockPool, maybe_await};

async fn example() {
    let pool = LockPool::<usize, 5, 32>::from_fn(|i| i);

    let g0 = maybe_await!(pool.get());
    assert_eq!(*g0, 0);
    let g1 = maybe_await!(pool.get());
    assert_eq!(*g1, 1);
    let g2 = maybe_await!(pool.get());
    assert_eq!(*g2, 2);
    let g3 = maybe_await!(pool.get());
    assert_eq!(*g3, 3);
    let g4 = maybe_await!(pool.get());
    assert_eq!(*g4, 4);

    assert!(pool.try_get().is_none());

    drop(g0);
    assert_eq!(*maybe_await!(pool.get()), 0);
}

体现 Rust 并发模型的核心,LockPool 是构建高性能、可靠的实时系统的基础,确保性能和公平性不相互排斥。

未来功能

  • get_or_create():用于获取或创建对象,使 API 对于某些连接池模式更加简单。

依赖

~0–25MB
~336K SLoC