16 个版本
新版本 0.3.1 | 2024年8月23日 |
---|---|
0.2.1 | 2024年5月15日 |
0.2.0-rc.5 | 2024年2月11日 |
0.2.0-rc.4 | 2023年8月31日 |
0.0.1 | 2022年6月22日 |
#312 在 并发 中排名
914 每月下载次数
被 4 个 Crates (3 直接) 使用
170KB
4K SLoC
ringbuf
无锁 SPSC FIFO 环形缓冲区,可直接访问内部数据。
特性
- 无锁操作 - 成功或失败立即发生,无需阻塞或等待。
- 任意项目类型(不仅限于
Copy
)。 - 可以逐个或一次性插入和删除项目。
- 线程安全地直接访问内部环形缓冲区内存。
Read
和Write
实现。- 支持覆盖插入。
- 不同类型的缓冲区和底层存储。
- 可以在不使用
std
的情况下使用,甚至无需使用alloc
(仅使用静态分配的内存)。 - 异步和阻塞版本(见 本节)。
用法
首先需要创建环形缓冲区本身。建议使用 HeapRb
,但您也可以 选择其他类型。
在创建环形缓冲区之后,它可以分成一对 Producer
和 Consumer
。生产者用于向环形缓冲区插入项目,消费者用于从中移除项目。
类型
提供了几种环形缓冲区类型
LocalRb
。仅适用于单线程使用。SharedRb
。可以在线程之间共享。其常用实例HeapRb
。内容存储在动态内存中。 在大多数情况下推荐使用。StaticRb
。内容可以存储在静态分配的内存中。
您还可以提供自己的泛型参数。
性能
SharedRb
需要在CPU核心之间同步CPU缓存。这种同步会有一些开销。为了避免多次不必要的同步,您可以使用一次操作多个项目的策略(如 push_slice
/push_iter
、pop_slice
/pop_iter
等),或者您可以选择 freeze
生产者或消费者,然后手动同步线程(请参阅 frozen
模块中的项目)。
对于单线程使用,推荐使用 LocalRb
,因为它比 SharedRb
快一点,因为没有CPU缓存同步。
示例
简单
use ringbuf::{traits::*, HeapRb};
let rb = HeapRb::<i32>::new(2);
let (mut prod, mut cons) = rb.split();
prod.try_push(0).unwrap();
prod.try_push(1).unwrap();
assert_eq!(prod.try_push(2), Err(2));
assert_eq!(cons.try_pop(), Some(0));
prod.try_push(2).unwrap();
assert_eq!(cons.try_pop(), Some(1));
assert_eq!(cons.try_pop(), Some(2));
assert_eq!(cons.try_pop(), None);
无堆
use ringbuf::{traits::*, StaticRb};
const RB_SIZE: usize = 1;
let mut rb = StaticRb::<i32, RB_SIZE>::default();
let (mut prod, mut cons) = rb.split_ref();
assert_eq!(prod.try_push(123), Ok(()));
assert_eq!(prod.try_push(321), Err(321));
assert_eq!(cons.try_pop(), Some(123));
assert_eq!(cons.try_pop(), None);
覆盖
环形缓冲区可以使用覆盖模式,当缓冲区满时,插入操作会覆盖最新元素。
use ringbuf::{traits::*, HeapRb};
let mut rb = HeapRb::<i32>::new(2);
assert_eq!(rb.push_overwrite(0), None);
assert_eq!(rb.push_overwrite(1), None);
assert_eq!(rb.push_overwrite(2), Some(0));
assert_eq!(rb.try_pop(), Some(1));
assert_eq!(rb.try_pop(), Some(2));
assert_eq!(rb.try_pop(), None);
请注意,push_overwrite
需要独占访问环形缓冲区,因此要并发执行,您需要使用互斥锁或其他锁来保护环形缓冲区。
派生crates
许可
根据您的选择,许可如下
- Apache License,版本 2.0 (LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献
除非您明确声明,否则根据 Apache-2.0 许可证定义的,您提交给作品的所有有意贡献都应按上述方式双许可,不附加任何额外条款或条件。
依赖关系
~0.7–1MB
~18K SLoC