Threads in Rust
In this lesson, you will learn how to work with threads in Rust. Threads allow your program to execute multiple tasks concurrently, improving performance and responsiveness.
Rust provides safe and low-level access to operating system threads through its standard library.
What Is a Thread?
A thread is the smallest unit of execution within a process. Multiple threads can run independently while sharing the same memory space.
Threads are commonly used for:
- Background processing
- Handling multiple user requests
- Parallel computations
- Improving application performance
Creating Threads in Rust
Rust uses the std::thread module to create and manage threads.
use std::thread;
fn main() {
thread::spawn(|| {
println!("Hello from a thread!");
});
}
This spawns a new thread that runs concurrently with the main thread.
Joining Threads
When a thread is created, Rust returns a JoinHandle.
You can use it to wait for the thread to finish execution.
use std::thread;
fn main() {
let handle = thread::spawn(|| {
println!("Thread is running");
});
handle.join().unwrap();
}
Calling join() blocks the main thread until the spawned thread completes.
Main Thread vs Child Threads
The main thread is the starting point of the program. If the main thread exits, all child threads are terminated.
That is why joining threads is important.
Using the move Keyword
Threads often need to access variables from the main thread.
Rust uses the move keyword to transfer ownership safely.
use std::thread;
fn main() {
let data = String::from("Rust");
let handle = thread::spawn(move || {
println!("{}", data);
});
handle.join().unwrap();
}
Once ownership is moved, the original variable cannot be used again.
Multiple Threads
You can spawn multiple threads to perform parallel tasks.
use std::thread;
fn main() {
let mut handles = vec![];
for i in 0..5 {
let handle = thread::spawn(move || {
println!("Thread {}", i);
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
}
Thread Scheduling
The operating system decides when each thread runs. The order of execution is not guaranteed.
This is why programs must not rely on execution order.
Thread Safety in Rust
Rust ensures thread safety using its type system.
- Data races are prevented at compile time
- Unsafe sharing is disallowed
- Only safe patterns are permitted
If your code compiles, it is thread-safe.
Common Thread Use Cases
Threads are useful when:
- Tasks can run independently
- Workload can be divided
- Blocking operations slow down execution
📝 Practice Exercises
Exercise 1
Create a thread that prints a number.
Exercise 2
Join a thread before program exit.
Exercise 3
Spawn three threads using a loop.
Exercise 4
Explain why joining threads is important.
✅ Practice Answers
Answer 1
thread::spawn(|| println!("1"));
Answer 2
let h = thread::spawn(|| {});
h.join().unwrap();
Answer 3
for i in 0..3 {
thread::spawn(move || println!("{}", i));
}
Answer 4
Joining ensures that threads complete execution before the program exits.
What’s Next?
In the next lesson, you will learn about Channels in Rust, which allow safe communication between threads.