Baiscs of Rust concurrency
Threads in Rust
use std::thread;
fn main() {
thread::spawn(f);
thread::spawn(f);
println!("Hello from the main thread.");
}
fn f() {
println!("Hello from another thread!");
let id = thread::current().id();
println!("This is my thread id: {id:?}");
}
- Two threads are spawned in the example from the main thread.
- Without joining the thread, main thread could exit before the spawned thread finish.
t1.join().unwrap(); t2.join().unwrap()
method waits until the thread has finished executing.
Scoped Threads
let numbers = vec![1, 2, 3];
thread::scope(|s| {
s.spawn(|| {
println!("length: {}", numbers.len());
});
s.spawn(|| {
for n in &numbers {
println!("{n}");
}
});
});
Scoped thread guarantees that none of the threads spawned in the scope can outlvie the scope.
- The scoped spawn method does not have
'static
bound on its argument type
Shared Onwership and Reference Counting
Borrowing and Data Races
-
Immutable borrow (
&data
)- Immutable reference can be copied.
- Access to the data it references is shared between all copies of such a reference.
- Compiler doesn't allow you to mutate something through this type of referece, since that might affect other coe that's currently borrowing the same data.
-
Mutable borrow (
&mut data
)- Active borrow of that data
- Ensures that mutating the data will note change anything that other code is currently looing at.