Threads
Rust provides built-in support for concurrent programming through its standard library module
std::thread.We can spawn threads using
std::thread::spawn, which takes a closure and runs it in a new thread.In a multi-threaded program, if we need shared mutable state, we can use:
Arc<T>: An atomic reference-counted smart pointer for shared ownership across threads.Mutex<T>: A synchronization primitive for mutual exclusion to safely access shared data.
Rust provides channels for thread communication in the
std::sync::mpscmodule.mpsc::channelcreates a transmitter (Sender) and a receiver (Receiver).Messages are sent via the transmitter and received via the receiver.
The
Sendercan be cloned tosendto the same channel multiple times, but only oneReceiveris supported.
threads1.rs
// This program spawns multiple threads that each runs for at least 250ms, and
// each thread returns how much time it took to complete. The program should
// wait until all the spawned threads have finished and should collect their
// return values into a vector.
use std::{
thread,
time::{Duration, Instant},
};
fn main() {
let mut handles = Vec::new();
for i in 0..10 {
let handle = thread::spawn(move || {
let start = Instant::now();
thread::sleep(Duration::from_millis(250));
println!("Thread {i} done");
start.elapsed().as_millis()
});
handles.push(handle);
}
let mut results = Vec::new();
for handle in handles {
// TODO: Collect the results of all threads into the `results` vector.
// Use the `JoinHandle` struct which is returned by `thread::spawn`.
results.push(handle.join().unwrap());
}
if results.len() != 10 {
panic!("Oh no! Some thread isn't done yet!");
}
println!();
for (i, result) in results.into_iter().enumerate() {
println!("Thread {i} took {result}ms");
}
}In this exercise we just need to wait the spawned thread to finish, get the result, and push it into
results.We can wait the thread to finish using
joinmethod.pub fn join(self) -> Result<T>: Waits for the associated thread to finish. This function will return immediately if the associated thread has already finished.
threads2.rs
In this exercise using
Arcdoesn't work because we also need mutability.So we should add
Mutex, A mutual exclusion primitive useful for protecting shared data.Mutex will block threads waiting for the lock to become available. The mutex can be created via a new constructor. Each mutex has a type parameter which represents the data that it is protecting. The data can only be accessed through the RAII guards returned from
lockandtry_lock, which guarantees that the data is only ever accessed when the mutex is locked.First we add mutex like this:
Then inside the spawned thread block we get
lockand update thejobs_donelike this:To get the value for print we can do the same with as above:
threads3.rs
In this exercise we learn how to use
channel.Because we will use two thread to send data we need to
clonetheSenderand use it on the first thread.The
Sendercan be cloned tosendto the same channel multiple times, but only oneReceiveris supported.
Last updated