Учебники

Rust — параллелизм

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

Потоки

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

Создание темы

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

//import the necessary modules
use std::thread;
use std::time::Duration;

fn main() {
   //create a new thread
   thread::spawn(|| {
      for i in 1..10 {
         println!("hi number {} from the spawned thread!", i);
         thread::sleep(Duration::from_millis(1));
      }
   });
   //code executed by the main thread
   for i in 1..5 {
      println!("hi number {} from the main thread!", i);
      thread::sleep(Duration::from_millis(1));
   }
}

Выход

hi number 1 from the main thread!
hi number 1 from the spawned thread!
hi number 2 from the main thread!
hi number 2 from the spawned thread!
hi number 3 from the main thread!
hi number 3 from the spawned thread!
hi number 4 from the spawned thread!
hi number 4 from the main thread!

Основной поток печатает значения от 1 до 4.

ПРИМЕЧАНИЕ. — Новый поток будет остановлен, когда основной поток закончится. Выходные данные из этой программы могут каждый раз немного отличаться.

Функция thread :: sleep заставляет поток остановить его выполнение на короткое время, позволяя запустить другой поток. Потоки, вероятно, по очереди, но это не гарантировано — это зависит от того, как операционная система планирует потоки. В этом прогоне основной поток печатается первым, даже если оператор кода из порожденного потока появляется первым в коде. Более того, даже если порожденная нить запрограммирована на печать значений до 9, она дошла только до 5, прежде чем основная нить закрылась.

Присоединиться Ручки

Появившаяся нить может не получить шанс запустить или запустить полностью. Это потому, что основной поток завершается быстро. Функция spawn <F, T> (f: F) -> JoinHandlelt; T> возвращает JoinHandle. Метод join () в JoinHandle ожидает завершения связанного потока.

use std::thread;
use std::time::Duration;

fn main() {
   let handle = thread::spawn(|| {
      for i in 1..10 {
         println!("hi number {} from the spawned thread!", i);
         thread::sleep(Duration::from_millis(1));
      }
   });
   for i in 1..5 {
      println!("hi number {} from the main thread!", i);
      thread::sleep(Duration::from_millis(1));
   }
   handle.join().unwrap();
}

Выход

hi number 1 from the main thread!
hi number 1 from the spawned thread!
hi number 2 from the spawned thread!
hi number 2 from the main thread!
hi number 3 from the spawned thread!
hi number 3 from the main thread!
hi number 4 from the main thread!
hi number 4 from the spawned thread!
hi number 5 from the spawned thread!
hi number 6 from the spawned thread!
hi number 7 from the spawned thread!
hi number 8 from the spawned thread!
hi number 9 from the spawned thread!

Основная нить и порожденная нить продолжают переключаться.

ПРИМЕЧАНИЕ. — Основной поток ожидает завершения созданного потока из-за вызова метода join () .