Day 4 - 1/5/2023
Concurrency
Starting with threads, variables are shared via scope
use std::thread; use std::time::Duration; fn main() { let s = String::from("hello") ; thread::scope(|scope| { scope.spawn(|| { println!("str: {}", s.as_str()); for i in 1..10 { println!("Count in thread: {i}! {s}"); thread::sleep(Duration::from_millis(5)); } }); scope.spawn(|| { thread::sleep(Duration::from_millis(500)); println!("new thread str: {}", s.as_str()); }); }); }
Channels
Available as Sender<T>
and Receiver<T>
, uses the module str::sync:mpsc
Unbounded and async channels with mpsc::channel
and bounded sync mpsc::sync_channel
fn main() { let (tx, rx) = mpsc::channel(); thread::spawn(move || { let thread_id = thread::current().id(); for i in 1..10 { tx.send(format!("Message {i}")).unwrap(); println!("{thread_id:?}: sent Message {i}"); } println!("{thread_id:?}: done"); }); thread::sleep(Duration::from_millis(100)); for msg in rx.iter() { println!("Main: got {}", msg); } }
Shared state
Arc<T>
allows shared read-only access via itsarc.clone()
methods across threads.Mutex<T>
ensure mutual exclusion and allows mutable access to T behind a read-only interface.
use std::thread; use std::sync::Arc; fn main() { let mut v = Arc::new("Shared data"); let mut handles = Vec::new(); for _ in 1..5 { let v = v.clone(); handles.push(thread::spawn(move || { println!("bla {v:?}") })) } handles.into_iter().for_each(|h| h.join().unwrap()); println!("v: {v:?}"); }