Consider this Rust program that shares state between threads using Arc and Mutex. What will it 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..5 {
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: {}", *counter.lock().unwrap());
}Think about how Arc and Mutex work together to allow safe shared access.
The Arc allows multiple ownership across threads, and Mutex ensures only one thread changes the value at a time. Each thread increments the counter once, so the final value is 5.
In Rust, which combination of types is commonly used to share mutable state safely across multiple threads?
One type provides thread-safe reference counting, the other provides mutual exclusion.
Arc is an atomic reference counter safe for threads, and Mutex provides exclusive mutable access. Together they allow safe shared mutable state.
What error will this Rust code produce?
use std::sync::Arc;
use std::thread;
fn main() {
let counter = Arc::new(0);
let mut handles = vec![];
for _ in 0..5 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
// Trying to increment counter directly
*counter += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Counter: {}", *counter);
}Think about mutability and thread safety with Arc.
Arc provides shared ownership but does not allow mutable access directly. Trying to mutate the inner value without synchronization causes a compile-time error.
Choose the Rust code snippet that correctly creates a thread-safe shared counter initialized to zero.
Remember which types are thread-safe and which are not.
Arc is thread-safe reference counting, and Mutex allows safe mutable access. Rc and RefCell are not thread-safe.
Given this Rust program, how many times will the shared counter be incremented?
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
for _ in 0..10 {
let mut num = counter.lock().unwrap();
*num += 1;
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Counter: {}", *counter.lock().unwrap());
}Count how many threads and increments each thread performs.
There are 10 threads, each incrementing the counter 10 times, so total increments are 100. The Mutex prevents data races.