Quelles sont les bonnes façons d'adapter cet exemple Barrier
pour gérer deux différences:Comment puis-je attendre la fin d'un nombre indéterminé de threads Rust sans utiliser de poignées de suivi?
le nombre d'éléments ne sont pas connus à l'avance (par exemple, dans le cas où la division d'un gros fichier en lignes)
sans suivre les poignées de fil (par exemple, sans utiliser le vecteur
handles
dans l'exemple ci-dessous). La motivation est que cela ajoute des frais généraux supplémentaires.
code Exemple:
use std::sync::{Arc, Barrier};
use std::thread;
let mut handles = Vec::with_capacity(10);
let barrier = Arc::new(Barrier::new(10));
for _ in 0..10 {
let c = barrier.clone();
handles.push(thread::spawn(move|| {
// do some work
c.wait();
}));
}
// Wait for other threads to finish.
for handle in handles {
handle.join().unwrap();
}
extrait de code
est adapté légèrement de la Barrier
docs.
La première chose qui m'a traversé l'esprit serait (si possible) de muter la valeur interne du Barrier
; cependant, l'API ne fournit pas d'accès modifiable à la propriété num_threads
de la structure Barrier
.
Une autre idée serait de ne pas utiliser le Barrier
et d'écrire à la place une logique personnalisée avec AtomicUsize
.
Je suis ouvert à l'apprentissage des façons les plus ergonomiques/idiomatiques de le faire dans Rust.
Est-ce à demander comment synchroniser les threads sans garder la trace des mécanismes de synchronisation de fil? Vous devez garder ces poignées quelque part si vous voulez les rejoindre plus tard. Puisque les vecteurs sont redimensionnables, qu'est-ce qui ne va pas avec la création et le maintien de ce nombre variable de poignées et d'instances de barrière? –