Выбрать главу

use std::thread;

// Это главный поток

fn main() {

// Это данные, которые мы будем обрабатывать.

// Мы посчитаем сумму всех чисел при помощи разделённого на потоки map-reduce алгоритма.

// Каждый фрагмент, разделённый пробелами, будет обрабатываться в отдельном потоке.

//

// TODO: посмотрите, что случится, если вы добавите пробелов!

let data = "86967897737416471853297327050364959

11861322575564723963297542624962850

70856234701860851907960690014725639

38397966707106094172783238747669219

52380795257888236525459303330302837

58495327135744041048897885734297812

69920216438980873548808413720956532

16278424637452589860345374828574668";

// Создадим вектор, который будет содержать созданные нам дочерние потоки.

let mut children = vec![];

/*************************************************************************

* "Map" фаза

*

* Разделим наши данные на сегменты и запустим начальную обработку

************************************************************************/

// Разделим наши данные на сегменты для индивидуального вычисления.

// Каждый фрагмент будет ссылкой (&str) на данные.

let chunked_data = data.split_whitespace();

// Обойдём сегменты данных.

// .enumerate() добавит в текущий цикл индекс элемента

// и далее полученный кортеж "(index, element)" будет немедленно

// "деструктурирован" на две переменные, "i" и "data_segment", при помощи

// "деструктурирующего присваивания"

for (i, data_segment) in chunked_data.enumerate() {

println!("{} сегмент данных \"{}\"", i, data_segment);

// Обработаем каждый сегмент данных в отдельном потоке

//

// `spawn()` вернёт ручку на новый поток,

// которую мы ДОЛЖНЫ сохранить, чтобы иметь доступ к возвращённому значению

//

// Синтаксис 'move || -> u32' обозначает замыкание, которое:

// * не имеет аргументов ('||')

// * забирает владение захваченных переменных ('move')

// * возвращает беззнаковое 32-битное целое число ('-> u32')

//

// Rust может вывести '-> u32' из самого замыкация,

// так что мы можем его опустить.

//

// TODO: попробуйте удалить 'move' и посмотреть что получится

children.push(thread::spawn(move || -> u32 {

// Вычислим промежуточную сумму этого сегмента:

let result = data_segment

// итерируемся по символам этого сегмента..

.chars()

// .. преобразуем текстовые символы в их числовые значения..

.map(|c| c.to_digit(10).expect("должно быть числом"))

// .. и суммируем получившийся итератор из чисел

.sum();

// `println!` блокирует стандартный вывод, так что чередования текста не происходит

println!("обработан сегмент {}, result={}", i, result);

// "return" не обязателен, так как Rust "язык выражений" и

// последнее выполненное выращение в каждом блоке автоматически становится значением этого блока.

result

}));

}

/*************************************************************************

* Фаза "Reduce"

*

* Собираем наши промежуточные значения и объединяем их в конечные результат

************************************************************************/

// собираем промежуточный результат каждого потока в новый вектор

let mut intermediate_sums = vec![];

for child in children {

// собираем возвращаемое значение каждого дочернего потока

let intermediate_sum = child.join().unwrap();

intermediate_sums.push(intermediate_sum);

}

// Объединяем все промежуточные суммы в одну конечную сумму.

//

// Мы используем "turbofish" `::<>` чтобы подсказать `sum()` тип.

//

// TODO: попробуйте без turbofish, явно указывая тип final_result

let final_result = intermediate_sums.iter().sum::<u32>();

println!("Финальная сумма: {}", final_result);

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX