Поймите подход Rust к параллелизму, основанный на концепции «бесстрашного параллелизма».

Параллелизм — это способность программы выполнять несколько задач одновременно на одном и том же ядре ЦП. Параллельные задачи выполняются и завершаются в перекрывающееся время без указания порядка, в отличие от параллелизма. когда различные задачи или подзадачи одной и той же задачи выполняются одновременно на оборудовании с несколькими процессоры.

Rust выделяется своими функциями производительности и поддержкой параллелизма безопасным и эффективным способом. Подход Rust к параллелизму основан на концепции «бесстрашного параллелизма», когда язык стремится упростить написание безопасного кода. параллельный код благодаря своей системе владения и заимствования, которая обеспечивает соблюдение строгих правил во время компиляции, чтобы предотвратить трассировку данных и обеспечить память безопасность.

Понимание параллелизма в Rust

Rust предоставляет несколько примитивов параллелизма для написания параллельных программ, включая потоки, передачу сообщений, мьютексы, атомарные типы и async/await для асинхронного программирования.

instagram viewer

Вот обзор примитивов параллелизма Rust:

  1. Потоки: Rust предоставляет станд:: поток модуль в своей стандартной библиотеке для создания потоков и управления ими. Вы можете создавать новые темы с помощью поток:: спавн функция. поток:: спавн принимает замыкание, содержащее код для выполнения. Вы также можете запускать потоки, которые могут выполняться параллельно, и Rust предоставляет примитивы синхронизации для координации их выполнения. Проверка заимствования гарантирует, что ссылки не приведут к неожиданному поведению.
  2. Передача сообщений: Модель параллелизма Rust поддерживает передачу сообщений между потоками. Вы будете использовать каналы, реализованные через std:: sync:: mpsc модуль для передачи сообщений. Канал состоит из передатчика (Отправитель) и приемник (Получатель). Потоки могут отправлять сообщения через передатчик и получать их через приемник. Это обеспечивает безопасный и синхронизированный способ связи между потоками.
  3. Мьютексы и атомарные типы: Rust предоставляет примитивы синхронизации, включая мьютексы (std:: sync:: Mutex) и атомарные типы (std:: sync:: атомный), чтобы обеспечить эксклюзивный доступ к совместному использованию данных. Мьютексы позволяют нескольким потокам одновременно обращаться к данным, предотвращая гонку данных. Атомарные типы обеспечивают атомарные операции над общими данными, такие как увеличение счетчика, не требуя явной блокировки.
  4. Async/Await и фьючерсы: Ржавчина асинхронный/Ждите Синтаксис предоставляет функциональные возможности для написания асинхронного кода, который можно выполнять одновременно. Асинхронные программы эффективно справляются с задачами, связанными с вводом-выводом, позволяя программам выполнять другие задачи, ожидая других операций ввода-вывода. ржавчины асинхронный/Ждите синтаксис основан на фьючерсах, и вы можете использовать их с помощью асинхронный стандарт или Токио библиотеки времени выполнения.

Потоки Rust легкие, а отсутствие накладных расходов во время выполнения делает их подходящими для высокопроизводительных приложений. Примитивы параллелизма Rust легко интегрируются с несколькими библиотеками и фреймворками для различных потребностей параллелизма.

Как использовать потоки спавна в Rust

Вы будете использовать станд:: поток модуль для порождения потоков. std:: thread:: spawn Функция позволяет вам создать новый поток, который будет выполняться одновременно с основным потоком или любыми другими существующими потоками в вашей программе.

Вот как вы можете создать поток с std:: thread:: spawn функция:

использовать стандарт:: поток;

фносновной() {
// Создаем новый поток
позволять thread_handle = thread:: spawn(|| {
// Здесь находится код, выполняемый в новом потоке
распечатать!("Привет из новой темы!");
});

// Ждем завершения созданного потока
thread_handle.join().unwrap();

// Код, выполняемый в основном потоке, продолжается здесь
распечатать!("Привет из главной темы!");
}

основной функция создает новый поток с поток:: спавн функцию, передав замыкание, содержащее код для выполнения в потоке (в данном случае замыкание является анонимной функцией). Замыкание выводит сообщение о том, что запущен новый поток.

присоединиться метод на thread_handle позволяет основному потоку ожидать завершения выполнения созданного потока. Позвонив присоединиться, функция гарантирует, что основной поток ожидает завершения порожденного потока, прежде чем продолжить.

Вы можете создать несколько потоков и использовать цикл или любой другой Структура контроля ржавчины для создания нескольких замыканий и создания потоков для каждого.

использовать стандарт:: поток;

фносновной() {
позволять число_потоков = 5;

позволятьмут thread_handles = век![];

для я в0..num_threads {
позволять thread_handle = thread:: spawn(двигаться || {
распечатать!("Привет из темы {}", я);
});
thread_handles.push(thread_handle);
}

для ручка в thread_handles {
ручка.присоединиться().развернуть();
}

распечатать!("Все темы завершены!");
}

Цикл for порождает пять потоков, каждому из которых назначается уникальный идентификатор. я с переменной цикла. Замыкания фиксируют значение я с двигаться ключевое слово, которого следует избегать вопросы собственности, и thread_handles вектор сохраняет потоки на потом в присоединиться петля.

После создания всех потоков основной функция перебирает thread_handles вектор, звонки присоединиться на каждом дескрипторе и ожидает выполнения всех потоков.

Передача сообщений по каналам

Вы можете передавать сообщения через потоки с каналами. Rust предоставляет функциональность для передачи сообщений в std:: sync:: mpsc модуль. Здесь, mpsc означает «несколько производителей, один потребитель» и позволяет общаться между несколькими потоками, отправляя и получая сообщения по каналам.

Вот как вы реализуете передачу сообщений по каналам межпотокового взаимодействия в своих программах:

использовать std:: sync:: mpsc;
использовать стандарт:: поток;

фносновной() {
// Создаем канал
позволять (отправитель, получатель) = mpsc:: channel();

// Создаем поток
поток:: спавн(двигаться || {
// Отправляем сообщение через канал
отправитель.отправить("Привет из треда!").развернуть();
});

// Получаем сообщение в основном потоке
позволять полученное_сообщение = приемник.recv().unwrap();
распечатать!("Получено сообщение: {}", полученное_сообщение);
}

основной функция создает канал с mpsc:: канал() который возвращает отправитель и получатель. отправитель отправляет сообщения на получатель который получает сообщения. основной функция продолжает порождать потоки и перемещать право собственности на Отправитель до закрытия резьбы. Внутри закрытия резьбы, отправитель.отправить() функция отправляет сообщение через канал.

приемник.recv() функция получает сообщение, останавливая выполнение до тех пор, пока поток не получит сообщение. основной Функция выводит сообщение на консоль после успешного получения сообщения.

Обратите внимание, что отправка сообщения через канал использует отправителя. Если вам нужно отправлять сообщения из нескольких потоков, вы можете клонировать отправителя с отправитель.клон() функция.

Кроме того, mpsc модуль предоставляет другие методы, такие как try_recv(), который в неблокирующем режиме пытается получить сообщение, и итер(), который создает итератор для полученных сообщений.

Передача сообщений по каналам обеспечивает безопасный и удобный способ связи между потоками, избегая гонки данных и обеспечивая правильную синхронизацию.

Модель владения и заимствования Rust гарантирует безопасность памяти

Rust сочетает в себе владение, заимствование и проверку заимствования, чтобы обеспечить надежную, безопасную среду параллельного программирования.

Средство проверки заимствования действует как подушка безопасности, обнаруживая потенциальные проблемы во время компиляции, а не полагаясь на проверки во время выполнения или сборку мусора.