Класс Barrier
Класс Barrier из модуля std::sync представляет собой примитив синхронизации, который заставляет несколько потоков остановиться и ждать, пока все они не достигнут определённой точки. Когда все потоки вызовут метод wait, они одновременно продолжат выполнение. Параметром конструктор new принимает количество потоков, которые должны собраться у барьера.
Класс Barrier полезен в ситуациях, когда нужно разбить вычисления на этапы и гарантировать, что все потоки завершат текущий этап прежде, чем начнётся следующий.
Синтаксис
use std::sync::Barrier;
let barrier = Barrier::new(n);
barrier.wait();
Пример
Давайте создадим барьер для трёх потоков и посмотрим, как они синхронизируются:
use std::sync::{Arc, Barrier};
use std::thread;
fn main()
{
let barrier = Arc::new(Barrier::new(3));
let mut handles = vec![];
for i in 0..3 {
let b = Arc::clone(&barrier);
handles.push(thread::spawn(move || {
println!("Поток {} начал работу", i);
b.wait();
println!("Поток {} продолжил работу", i);
}));
}
for handle in handles {
handle.join().unwrap();
}
}
Результат выполнения кода:
Поток 0 начал работу
Поток 1 начал работу
Поток 2 начал работу
Поток 0 продолжил работу
Поток 1 продолжил работу
Поток 2 продолжил работу
Пример
Давайте используем барьер в цикле для синхронизации нескольких этапов вычислений:
use std::sync::{Arc, Barrier};
use std::thread;
fn main()
{
let barrier = Arc::new(Barrier::new(2));
let mut handles = vec![];
for i in 0..2 {
let b = Arc::clone(&barrier);
handles.push(thread::spawn(move || {
for step in 1..=3 {
println!("Поток {} на шаге {}", i, step);
b.wait();
}
}));
}
for handle in handles {
handle.join().unwrap();
}
}
Результат выполнения кода:
Поток 0 на шаге 1
Поток 1 на шаге 1
Поток 0 на шаге 2
Поток 1 на шаге 2
Поток 0 на шаге 3
Поток 1 на шаге 3