TGViewer
Rust Rust @rust_code · 8.92K subscribers
Post #932 4.42K
👣 Задача: "Безопасная многопоточная очередь с приоритетами в Rust"

📌 Условие:

Реализуйте потокобезопасную структуру данных — очередь с приоритетами (`PriorityQueue`), которая:

- Позволяет добавлять элементы с приоритетом через push(value: T, priority: u32).
- Позволяет забирать элемент с наивысшим приоритетом через pop() -> Option<T>.
- Гарантирует:
- Безопасную работу из нескольких потоков без блокировок на долгие периоды (желательно через минимальные локи или атомарные операции).
- Отдачу элементов в порядке убывания приоритета.
- Высокую производительность при массовых операциях.

Ограничения:

- Можно использовать стандартные библиотеки Rust (`std::sync`, `std::collections`).
- Нельзя использовать внешние библиотеки вроде tokio, crossbeam, rayon и др.
- Структура должна быть универсальной (`Generic`), т.е. работать с любыми типами данных.

---

▪️ Подсказки:

- Для внутреннего хранения можно использовать BinaryHeap из std::collections.
- Для обеспечения многопоточности можно использовать Arc<Mutex<...>>.
- Чтобы минимизировать блокировки, можно подумать о:
- Разделении кучи на несколько шардов (`sharding`),
- Использовании тонкой блокировки только на операции изменения состояния.

---

▪️ Что оценивается:

- Умение правильно работать с владением (`ownership`) и заимствованием (`borrowing`) в многопоточной среде.
- Аккуратное управление блокировками (`Mutex`, `RwLock`).
- Оптимизация под высокую нагрузку (минимизация времени блокировки).
- Чистота и читабельность кода.
- Способность правильно обрабатывать ошибки (`PoisonError` при падении потока).

---

▪️ Разбор возможного решения:

Идея архитектуры:

- Основная структура — Arc<Mutex<BinaryHeap<...>>>.
- Каждый push и pop блокирует мьютекс на короткое время (захватывает лок на минимальное изменение).
- При push(value, priority):
- Оборачиваем значение в структуру, которая реализует Ord так, чтобы приоритет был главным критерием сортировки.
- При pop():
- Просто pop() из BinaryHeap.
- Обработка ошибок:
- При отравлении мьютекса (`PoisonError`) безопасно восстанавливать структуру или пробрасывать ошибку выше.

---

▪️ Мини-пример структуры:


use std::collections::BinaryHeap;
use std::sync::{Arc, Mutex};

#[derive(Eq, PartialEq)]
struct Item<T> {
priority: u32,
value: T,
}

impl<T> Ord for Item<T> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
other.priority.cmp(&self.priority) // обратный порядок для max-heap
}
}

impl<T> PartialOrd for Item<T> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}

pub struct PriorityQueue<T> {
heap: Arc<Mutex<BinaryHeap<Item<T>>>>,
}

impl<T> PriorityQueue<T> {
pub fn new() -> Self {
PriorityQueue {
heap: Arc::new(Mutex::new(BinaryHeap::new())),
}
}

pub fn push(&self, value: T, priority: u32) {
let mut heap = self.heap.lock().unwrap();
heap.push(Item { priority, value });
}

pub fn pop(&self) -> Option<T> {
let mut heap = self.heap.lock().unwrap();
heap.pop().map(|item| item.value)
}
}


---

▪️ Возможные подводные камни:

- ❗ Не обработать PoisonError — если поток паникует при блокировке, вся очередь будет "сломана".
- ❗ Долгая блокировка внутри push или pop, особенно при больших объемах данных.
- ❗ Возможная гонка состояний, если попытаться вручную обойти Mutex через небезопасный код (`unsafe`).

---

▪️ Дополнительные вопросы на собеседовании:

- Как модифицировать структуру для поддержки тайм-аутов на pop() (если очередь пуста — ждать максимум N миллисекунд)?
- Как бы вы реализовали "разделение очереди на несколько шардов" для снижения конкуренции потоков?
- Как сделать неблокирующую версию через Atomic примитивы?

---

@rust_code
  • 👍 22
  • 🔥 8
  • ❤ 5
  • 😁 2
  • 🥰 1
More from @rust_code
  1. Sep 28, 2026🦀 Qt открывает Rust полноценный путь к кроссплатформенному UI Qt представила Qt Bridge fo…
  2. Sep 26, 2026Как создать пустой vector по-гениальному
  3. Sep 24, 2026🦀 Как доказать, что Rust-код работает правильно: Amazon рассказывает о Verus Rust предотв…
  4. Sep 24, 2026❌В IT сейчас кризис джунов, но только не в кибербезе. ❗️Рынку не хватает 50 000 специалист…
  5. Sep 24, 2026Rust без аллокатора: `fff` снизил пиковое потребление памяти через `mmap` Во время тестиро…
  6. Sep 23, 2026photo post
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →