Plain Threads
Rust threads work similarly to threads in other languages:
use std::thread;
use std::time::Duration;
fn main() {
thread::spawn(|| {
for i in 0..10 {
println!("Count in thread: {i}!");
thread::sleep(Duration::from_millis(5));
}
});
for i in 0..5 {
println!("Main thread: {i}");
thread::sleep(Duration::from_millis(5));
}
}
- Spawning new threads does not automatically delay program termination at the end of
main
. - Thread panics are independent of each other.
- Panics can carry a payload, which can be unpacked with Any::downcast_ref.
This slide should take about 15 minutes.
Run the example.
- 5ms timing is loose enough that main and spawned threads stay mostly in lockstep.
- Notice that the program ends before the spawned thread reaches 10!
- This is because
main
ends the program and spawned threads do not make it persist.- Compare to
pthreads
/C++std::thread
/boost::thread
if desired.
- Compare to
How do we wait around for the spawned thread to complete?
thread::spawn returns a
JoinHandle
. Look at the docs.JoinHandle
has a .join() method that blocks.
Use
let handle = thread::spawn(...)
and laterhandle.join()
to wait for the thread to finish and have the program count all the way to 10.Now what if we want to return a value?
Look at docs again:
- thread::spawn‘s closure returns
T
JoinHandle
.join() returnsthread::Result<T>
- thread::spawn‘s closure returns
Use the
Result
return value fromhandle.join()
to get access to the returned value.Ok, what about the other case?
- Trigger a panic in the thread. Note that this doesn’t panic
main
. - Access the panic payload. This is a good time to talk about Any.
- Trigger a panic in the thread. Note that this doesn’t panic
Now we can return values from threads! What about taking inputs?
- Capture something by reference in the thread closure.
- An error message indicates we must move it.
- Move it in, see we can compute and then return a derived value.
If we want to borrow?
- Main kills child threads when it returns, but another function would just return and leave them running.
- That would be stack use-after-return, which violates memory safety!
- How do we avoid this? See next slide.