Rust - Concurrence

Dans la programmation simultanée, différentes parties d'un programme s'exécutent indépendamment. D'autre part, dans la programmation parallèle, différentes parties d'un programme s'exécutent en même temps. Les deux modèles sont tout aussi importants car davantage d'ordinateurs tirent parti de leurs multiples processeurs.

Fils

Nous pouvons utiliser des threads pour exécuter des codes simultanément. Dans les systèmes d'exploitation actuels, le code d'un programme exécuté est exécuté dans un processus et le système d'exploitation gère plusieurs processus à la fois. Dans votre programme, vous pouvez également avoir des parties indépendantes qui s'exécutent simultanément. Les fonctionnalités qui exécutent ces pièces indépendantes sont appelées threads.

Créer un fil

le thread::spawnLa fonction est utilisée pour créer un nouveau thread. La fonction spawn prend une fermeture comme paramètre. La fermeture définit le code qui doit être exécuté par le thread. L'exemple suivant imprime du texte à partir d'un fil principal et d'autres textes à partir d'un nouveau fil.

//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));
   }
}

Production

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!

Le thread principal imprime les valeurs de 1 à 4.

NOTE- Le nouveau fil sera arrêté à la fin du fil principal. La sortie de ce programme peut être un peu différente à chaque fois.

le thread::sleepLa fonction force un thread à arrêter son exécution pendant une courte durée, permettant à un thread différent de s'exécuter. Les threads se relaient probablement, mais ce n'est pas garanti - cela dépend de la façon dont le système d'exploitation planifie les threads. Dans cette exécution, le thread principal est imprimé en premier, même si l'instruction d'impression du thread généré apparaît en premier dans le code. De plus, même si le thread généré est programmé pour imprimer des valeurs jusqu'à 9, il n'est arrivé qu'à 5 avant que le thread principal ne s'arrête.

Joindre les poignées

Un thread généré peut ne pas avoir la possibilité de s'exécuter ou de s'exécuter complètement. C'est parce que le thread principal se termine rapidement. La fonction spawn <F, T> (f: F) -> JoinHandlelt; T> renvoie un JoinHandle. La méthode join () sur JoinHandle attend que le thread associé se termine.

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();
}

Production

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!

Le thread principal et le thread généré continuent de basculer.

NOTE - Le thread principal attend que le thread généré se termine en raison de l'appel au join() méthode.