Bonjour à tous,
Un problème retors de durée de vie se pose à moi, que j'ai grandement simplifié ici...
Je partage un AtomicU8 entre plusieurs treads. Ces derniers n'ont aucune durée de vie qui dépasse la fonction qui les appelle.
Pourtant le compilateur se plaint "`a` does not live long enough" et demande que l'"argument requires that `a` is borrowed for `'static`".
Code rust : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 use std::thread::{self, JoinHandle}; use std::sync::atomic::{AtomicU8, Ordering}; fn lanceur() { let a = AtomicU8::new( 0 ); let mut vecteur: Vec<JoinHandle<()>> = Vec::new(); for i in 1..10 { let y = i; let ref_a = &a; vecteur.push( thread::spawn( move || { println!("n = {}", y); ref_a.fetch_add(y, Ordering::SeqCst); } ) ); } for v in vecteur { v.join(); } println!( "{}", a.load( Ordering::Relaxed ) ); } fn main() { lanceur(); // je suis sûr que mes threads lancés dans cette fonction, n'auront pas une durée plus longue qu'elle }
Jusque là d'accord : j'imagine qu'il ne cherche pas à savoir s'il peut connaître la durée de vie d'un thread, et donc demande forcément une référence statique.
Grand seigneur que je suis, je m'exécute :
Code rust : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 fn lanceur() { static a: std::sync::atomic::AtomicU8 = AtomicU8::new( 0 ); ...
Pas de problème : ça compile, et ça me donne bien 45. Parfait. Ou presque. Car comme j'ai mis 'a' en statique, évidemment un second appel me retourne 90 :
Code rust : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 fn main() { lanceur(); // a = 45 lanceur(); // a = 45+45 = 90 }
Du coup si j'ai l'outrecuidance d'avoir ma fonction "lanceur" elle-même dans un thread, je pars évidemment dans le décor (certes le résultat final sera toujours le même).
Code rust : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 fn main() { let mut vecteur: Vec<JoinHandle<()>> = Vec::new(); for y in 0..5 { vecteur.push( thread::spawn( || { lanceur(); } ) ); } for v in vecteur { v.join(); } }
Là je sèche. Comment négocier une durée de vie dans un tel cas, finalement assez commun ? J'ai regardé les docs sur les durées de vie sans trouver une piste.
Précision : ici j'ai partagé directement mon AtomicU8. Dans la réalité de mon code, je passe par une structure pour le partage avec quelques autres champs. La structure est d'ailleurs créée pour être possédée par le thread.
Votre aide me serait précieuse...
Bonne journée à tous,
Julien.
Partager