The Send trait guarantees that ownership of a type can be safely transferred to another thread.
Click to reveal answer
beginner
What is the purpose of the Sync trait in Rust?
The Sync trait means a type can be safely referenced from multiple threads at the same time.
Click to reveal answer
intermediate
Why does Rust prevent data races at compile time?
Rust uses ownership, borrowing rules, and traits like Send and Sync to ensure no two threads can simultaneously access mutable data without synchronization, preventing data races.
Click to reveal answer
intermediate
How does Rust's type system help with concurrency safety?
Rust's type system enforces rules that prevent unsafe sharing of data across threads by requiring types to implement Send and Sync traits for thread transfer and shared access.
Click to reveal answer
beginner
What happens if a type does not implement Send or Sync?
If a type does not implement Send or Sync, Rust will not allow it to be transferred or shared across threads, preventing unsafe concurrent access.
Click to reveal answer
Which Rust trait allows a type to be safely transferred between threads?
AClone
BSend
CCopy
DSync
✗ Incorrect
The Send trait marks types that can be safely moved to another thread.
What does the Sync trait ensure?
AA type can be referenced from multiple threads safely
BA type can be copied
CA type can be cloned
DA type can be sent to another process
✗ Incorrect
Sync means it is safe for multiple threads to have references to the same data.
Why does Rust prevent data races at compile time?
ABecause Rust uses garbage collection
BBecause Rust uses runtime checks
CBecause Rust disables multithreading
DBecause Rust enforces ownership and borrowing rules
✗ Incorrect
Rust's ownership and borrowing rules prevent unsafe concurrent mutable access.
If a type is not Send, what does Rust do?
APrevents it from being transferred between threads
BAllows it to be sent between threads anyway
CAutomatically implements <code>Send</code> for it
DIgnores thread safety
✗ Incorrect
Rust will not allow types that are not Send to be moved across threads.
Which of these is NOT a concurrency safety guarantee in Rust?
ANo data races
BSafe transfer of ownership between threads
CAutomatic locking of all variables
DSafe shared references across threads
✗ Incorrect
Rust does not automatically lock variables; it enforces safety through types and traits.
Explain how Rust uses the Send and Sync traits to guarantee concurrency safety.
Think about what each trait allows in terms of thread interaction.
You got /5 concepts.
Describe why Rust's compile-time checks prevent data races in concurrent programs.
Focus on how Rust controls access to data across threads.
You got /5 concepts.
Practice
(1/5)
1. Which Rust type is used to safely share ownership of data across multiple threads?
easy
A. Rc
B. Box
C. Arc
D. RefCell
Solution
Step 1: Understand ownership sharing in concurrency
In Rust, Arc (Atomic Reference Counted) allows multiple threads to share ownership safely.
Step 2: Compare other options
Box is for single ownership, Rc is not thread-safe, and RefCell is for interior mutability but not thread-safe.
Final Answer:
Arc -> Option C
Quick Check:
Safe shared ownership across threads = Arc [OK]
Hint: Arc is for thread-safe shared ownership [OK]
Common Mistakes:
Confusing Rc with Arc for multithreading
Using Box for shared ownership
Thinking RefCell is thread-safe
2. Which of the following is the correct syntax to create a Mutex protecting an integer value 5?
easy
A. let m = Mutex::new(5);
B. let m = Mutex(5);
C. let m = new Mutex(5);
D. let m = Mutex::create(5);
Solution
Step 1: Recall Mutex creation syntax
In Rust, you create a Mutex by calling Mutex::new(value).
Step 2: Check each option
Only let m = Mutex::new(5); uses the correct Mutex::new(5) syntax; others are invalid.
Final Answer:
let m = Mutex::new(5); -> Option A
Quick Check:
Mutex creation uses Mutex::new() [OK]
Hint: Use Mutex::new(value) to create a Mutex [OK]
Common Mistakes:
Omitting ::new when creating Mutex
Using constructor syntax like Mutex(5)
Confusing new() with create()
3. What will the following Rust code print?
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..3 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("{}", *counter.lock().unwrap());
}
medium
A. 0
B. 3
C. Compilation error
D. 1
Solution
Step 1: Understand the code's concurrency logic
The code creates 3 threads, each increments the shared counter by 1 inside a Mutex lock.
Step 2: Calculate the final counter value
Each thread adds 1, so total increments = 3. The final print shows 3.
Ignoring Mutex lock and thinking of race conditions
Assuming only one thread runs
Expecting compilation error due to Arc usage
4. Identify the error in this Rust code snippet that tries to share a vector across threads:
use std::sync::Arc;
use std::thread;
fn main() {
let numbers = vec![1, 2, 3];
let shared_numbers = Arc::new(numbers);
let handle = thread::spawn(move || {
shared_numbers.push(4);
});
handle.join().unwrap();
}
medium
A. Vector is not thread-safe without Mutex or RwLock
B. Arc does not implement Send for Vec<T>
C. Cannot move vector into Arc
D. Missing clone of Arc before move
Solution
Step 1: Examine the thread code
The thread attempts to mutate the shared Arc<Vec<i32>> by calling push, but Arc provides only shared immutable access.
Step 2: Recall requirements for mutable shared data
To mutate data shared across threads, wrap it in Mutex or RwLock inside the Arc, e.g., Arc<Mutex<Vec<i32>>>.
Step 3: Eliminate other options
A: Vec can be moved into Arc. B: Arc<Vec<T>> implements Send/Sync for T: Sync. D: Clone not needed for single-thread move.
Final Answer:
Vector is not thread-safe without Mutex or RwLock -> Option A
Quick Check:
Mutable shared data needs Mutex or RwLock [OK]
Hint: Mutable shared data needs Mutex or RwLock [OK]
Common Mistakes:
Thinking Arc alone makes data mutable and safe
Confusing Send trait errors
Assuming clone is needed before move
5. You want to safely share and mutate a HashMap across multiple threads in Rust. Which combination of types ensures concurrency safety and allows mutation?
hard
A. Arc<RefCell<HashMap<String, i32>>>
B. Mutex<HashMap<String, i32>>
C. Rc<RefCell<HashMap<String, i32>>>
D. Arc<RwLock<HashMap<String, i32>>>
Solution
Step 1: Identify thread-safe shared ownership
To share data across threads, Arc is needed for atomic reference counting.
Step 2: Choose synchronization primitive for mutation
For mutable access, Mutex or RwLock can be used. RwLock allows multiple readers or one writer, improving concurrency.
Step 3: Evaluate options
Arc<RefCell<HashMap<String, i32>>> uses RefCell which is not Sync and thus not thread-safe. Arc<RwLock<HashMap<String, i32>>> uses RwLock which is suitable for read-heavy workloads with mutations. Rc<RefCell<HashMap<String, i32>>> uses Rc and RefCell, which are not thread-safe. Mutex<HashMap<String, i32>> lacks Arc, so no shared ownership across threads.
Final Answer:
Arc<RwLock<HashMap<String, i32>>> -> Option D
Quick Check:
Arc + RwLock = safe shared mutable access [OK]
Hint: Use Arc with RwLock for shared mutable access [OK]
Common Mistakes:
Using Rc or RefCell for multithreading
Omitting Arc for shared ownership
Choosing Mutex over RwLock without reason
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.