Когда в программе используется несколько потоков, выполняющих задачи, которые зависят от завершения друг друга, то на первый план выходит проблема координации потоков.
Rust предоставляет удобный способ координации потоков с помощью барьеров из модуля std::sync.
Барьеры могут помочь эффективно координировать потоки, гарантируя, что они синхронизируют свою работу в определенных точках программы. Такая координация имеет решающее значение для сценариев, в которых разные потоки должны сотрудничать для достижения общей цели, например, для параллельной обработки, планирования задач или распределенных вычислений.
Рассмотрим небольшой пример:
use std::sync::{Arc, Barrier};
use std::thread;
fn main() {
// создаем барьер
// число 3 указывает, что барьер должен ждать завершения 3 потоков
let barrier = Arc::new(Barrier::new(3));
let mut threads = vec![];
// создаем 3 потока
for id in 0..3 {
// клонируем барьер для передачи в поток
let barrier = Arc::clone(&barrier);
// создаем поток
let new_thread = thread::spawn(move || {
println!("Thread {} started", id);
thread::sleep(std::time::Duration::from_secs(2)); // имитация работы
println!("Thread {} finished", id);
// ожидаем завершения других потоков
barrier.wait();
println!("Thread {} reached the barrier", id);
});
threads.push(new_thread);
}
// ждем завершения потоков
for t in threads { t.join().unwrap(); }
}
Здесь мы создаем барьер со счетчиком 3, указывая, что он должен дождаться, пока три потока достигнут его, прежде чем разрешить им продолжить работу:
let barrier = Arc::new(Barrier::new(3));
Опять же обертываем барьер в Arc для использования в других потоках.
Далее для демонстрации запускаем 3 потока, передавая в каждый из них копию барьера.
let barrier = Arc::clone(&barrier);
let new_thread = thread::spawn(move || {
println!("Thread {} started", id);
thread::sleep(std::time::Duration::from_secs(2)); // имитация работы
println!("Thread {} finished", id);
Для имитации работы каждого потока используется задержка в 2 секунды. А затем поток ждет, пока другие потоки достигнут барьера:
barrier.wait();
Пример результата работы программы:
Thread 0 started Thread 1 started Thread 2 started Thread 0 finished Thread 2 finished Thread 1 finished Thread 1 reached the barrier Thread 2 reached the barrier Thread 0 reached the barrier