Crates.io | spmcq |
lib.rs | spmcq |
version | 0.1.0 |
source | src |
created_at | 2024-01-22 05:45:55.85321 |
updated_at | 2024-01-22 05:45:55.85321 |
description | A Rust library for a thread-safe single-producer, multiple-consumer bounded ring buffer (FIFO queue) |
homepage | |
repository | https://github.com/timstr/spmcq |
max_upload_size | |
id | 1108351 |
size | 32,873 |
A Rust library for a thread-safe single-producer, multiple-consumer bounded ring buffer (FIFO queue).
This library was written with real-time audio applications in mind, where a typical scenario would be something like the following:
Features:
The high-level API is somewhat similar to that of std::sync::mpsc::sync_channel
. Choose a fixed size capacity and call ring_buffer
with that size to receive a Reader<T>
and a Writer<T>
. Both can be passed to different threads, and Reader<T>
can be cloned. Writer::write
pushes a new value onto the buffer. Reader::read
attempts to read the next value in its own sequence.
let (mut reader, mut writer) = ring_buffer::<usize>(256);
std::thread::spawn(move ||{
for i in 1000 {
writer.write(i);
std::thread::sleep(Duration::from_millis(1))
}
});
std::thread::spawn(move ||{
loop {
match reader.read() {
ReadResult::Ok(i) => println!("Received {}", i),
ReadResult::Dropout(i) => println!("Received {} but lost some values", i),
ReadResult::Empty(i) => println("No new data"),
}
std::thread::sleep(Duration::from_millis(1));
}
});
If a reader has fully caught up to the writer, read()
will return ReadResult::Empty
until more is written. If the reader is somewhere between the front and the back of the queue, read()
will return ReadResult::Ok(_)
containing its next value. Otherwise, if the writer has completely overtaken a reader, its read()
method returns ReadResult::Dropout(_)
, which informs that the reader has fallen at least one lap behind since its last read, but still returns a value from the current lap.
In order to skip a reader to the front of the queue, call Reader::skip_ahead()
. The next read will always return ReadResult::Dropout(_)
, but any accumulated latency can be cut down this way if dropped values are tolerable.
The stored data type T
must be Copy
. This constraint allows minimizing the time that readers spend holding a read lock on each item, since the lock must be held only long enough to do a memcpy of the item.