Threads overview in Rust - Time & Space Complexity
When using threads, we want to know how the program's work grows as we add more tasks or data.
We ask: How does running multiple threads affect the total steps the program takes?
Analyze the time complexity of the following code snippet.
use std::thread;
fn main() {
let mut handles = vec![];
for i in 0..5 {
handles.push(thread::spawn(move || {
println!("Thread {} is running", i);
}));
}
for handle in handles {
handle.join().unwrap();
}
}
This code creates 5 threads, each printing a message, then waits for all to finish.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Loop creating and running 5 threads.
- How many times: 5 times, once per thread.
As the number of threads increases, the total work grows roughly the same amount.
| Input Size (n) | Approx. Operations |
|---|---|
| 5 | 5 thread creations and joins |
| 10 | 10 thread creations and joins |
| 100 | 100 thread creations and joins |
Pattern observation: Doubling threads roughly doubles the work done.
Time Complexity: O(n)
This means the total steps grow directly with the number of threads created.
[X] Wrong: "Adding more threads makes the program run faster without extra cost."
[OK] Correct: Creating and managing threads takes time, so more threads mean more work overall.
Understanding how threads add work helps you explain program speed and resource use clearly.
"What if we changed the number of threads to grow with input size? How would the time complexity change?"
Practice
Solution
Step 1: Understand what threads do
Threads allow a program to perform multiple tasks simultaneously, improving efficiency.Step 2: Match purpose with options
Only To run multiple parts of a program at the same time correctly states that threads run parts of a program at the same time.Final Answer:
To run multiple parts of a program at the same time -> Option DQuick Check:
Threads = run tasks simultaneously [OK]
- Thinking threads slow down the program
- Confusing threads with functions
- Believing threads remove variables
Solution
Step 1: Recall Rust thread syntax
Rust usesthread::spawnto create a new thread.Step 2: Compare options with correct syntax
Only thread::spawn(|| println!("Hello")); usesthread::spawncorrectly.Final Answer:
thread::spawn(|| println!("Hello")); -> Option BQuick Check:
Start thread = thread::spawn [OK]
- Using thread::start instead of spawn
- Using thread::run or thread::create which don't exist
- Missing the closure syntax ||
use std::thread;
fn main() {
let handle = thread::spawn(|| {
println!("Inside thread");
});
handle.join().unwrap();
println!("Thread finished");
}Solution
Step 1: Understand thread::spawn and join
The thread prints "Inside thread". The main thread waits for it to finish using join().Step 2: Determine print order
Because join() waits, "Inside thread" prints first, then "Thread finished" prints.Final Answer:
Inside thread Thread finished -> Option AQuick Check:
join() waits, so inside thread prints before main [OK]
- Assuming main prints first without waiting
- Ignoring join() effect
- Expecting only one print line
use std::thread;
fn main() {
let handle = thread::spawn(|| {
println!("Hello from thread");
});
println!("Main thread");
}Solution
Step 1: Check thread usage
The code starts a thread but does not wait for it to finish with join().Step 2: Understand consequences
Without join(), the main thread may finish and exit before the spawned thread prints.Final Answer:
Missing call to join(), so main may end before thread finishes -> Option AQuick Check:
Always join threads to ensure they complete [OK]
- Forgetting to call join()
- Thinking thread::spawn syntax is wrong
- Assuming println! is incorrect
Solution
Step 1: Understand thread creation and waiting
To ensure "Done" prints after both threads finish, we must join both threads before printing.Step 2: Analyze options for correct join usage
let t1 = thread::spawn(|| println!("Thread 1")); let t2 = thread::spawn(|| println!("Thread 2")); t1.join().unwrap(); t2.join().unwrap(); println!("Done"); creates two threads, joins both, then prints "Done". This guarantees order.Final Answer:
let t1 = thread::spawn(|| println!("Thread 1")); let t2 = thread::spawn(|| println!("Thread 2")); t1.join().unwrap(); t2.join().unwrap(); println!("Done"); -> Option CQuick Check:
Join all threads before final print to ensure order [OK]
- Not joining threads before printing "Done"
- Joining threads immediately after spawn (serializing)
- Spawning extra thread for "Done" message
Ready to prove it?
Pass the test and this pattern moves unknown
