Какие кольцевые lock free очереди / каналы доступны для использования в Rust?

Какие существуют кольцевые lock free очереди / каналы вы используете для Rust? Я попробовал использовать std::sync::mpsc::channel, но его скорость оказалась недостаточной. Я хочу избежать использования блокировщиков и использовать только atomic, так как у нас по сути spsc. Также мне нужно, чтобы метод dequeue ждал, пока не будет хотя бы каких-то данных, но большинство очередей возвращают None, когда пустые.
  • 11 января 2024 г. 18:39
Ответы на вопрос 2
Для реализации lock-free кольцевых очередей (также известных как кольцевые буферы или кольцевые FIFO) в Rust, обычно используются внешние библиотеки, поскольку стандартная библиотека Rust не предоставляет таких структур данных. Эти очереди обычно основываются на атомарных операциях для синхронизации, что позволяет избежать блокировок и обеспечивает высокое быстродействие. 

Вот некоторые популярные кольцевые lock-free очереди в экосистеме Rust:

1. **crossbeam-channel**: Расширенная версия стандартного `std::sync::mpsc` с более высокой производительностью и дополнительными возможностями. `crossbeam-channel` предоставляет многопоточные каналы для обмена сообщениями между потоками, и хотя он не реализован как строго кольцевой буфер, идеология lock-free доступа здесь присутствует.

2. **flume**: Ещё одна альтернатива `std::sync::mpsc`. `flume` предлагает как lock-free, так и не lock-free реализации каналов, в зависимости от конкретных потребностей. 

3. **ringbuf**: Представляет собой lock-free SPSC (Single Producer Single Consumer) кольцевой буфер. Это библиотека, которая подойдёт вам, если у вас есть строго один производитель и один потребитель.

4. **disruptor** (или **LMAX Disruptor**): Lock-free многопроизводительный и многопотребительный кольцевой буфер, вдохновлённый Java LMAX Disruptor, может быть использован для сценариев с высокой пропускной способностью.

5. **conqueue**: Это lock-free очередь, предназначенная для множества производителей и потребителей (MPMC).

Чтобы удовлетворить ваше требование ожидания данных перед дефрагментацией, вы можете использовать механизм блокирования потока или условные переменные в комбинации с упомянутыми lock-free очередями. Однако, если вы хотите полностью избежать блокирования, вам нужно использовать цикл опроса с некоторой формой ожидания (например, усыпление на сон микросекунд).

Пример использования `ringbuf` в Rust может выглядеть следующим образом:

```rust
use ringbuf::RingBuffer;

fn main() {
    let (mut prod, mut cons) = RingBuffer::new(1024).split();

    // Producer thread
    std::thread::spawn(move || {
        for i in 0..10 {
            loop {
                if prod.push(i).is_ok() {
                    // Successfully pushed item into the buffer
                    break;
                }
                // Optional: yield the thread or sleep for a tiny bit
            }
        }
    });

    // Consumer thread
    std::thread::spawn(move || {
        for _ in 0..10 {
            loop {
                match cons.pop() {
                    Some(v) => {
                        println!("Consumed: {}", v);
                        // Successfully popped item from the buffer
                        break;
                    }
                    None => {
                        // Buffer is empty, you might want to wait or yield/sleep
                    }
                }
            }
        }
    });
}
```
Конкретный выбор библиотеки будет зависеть от вашего конкрет
Тебе не нужно никакое кольцо. Ищи просто lock-free очереди. Если будет кольцо 
- то тебе не хватит памяти и нужно будет придумывать механизм выхода из
ситуации (хопа привет блокировка).
Похожие вопросы