Concurrency Quiz - Languages Rust
Free practice quiz: Concurrency (Languages Rust). 55 multiple-choice questions with answers and explanations. Play online, no sign-up needed.
This Languages Rust practice quiz has 55 multiple-choice questions on Concurrency, and 55 of them come with an explanation. Try the 5 sample questions below (tap an option to check yourself), then play the full quiz online. No sign-up needed.
Start quiz: 55 questions, freeSample questions
What fundamental primitive does Rust use to manage shared mutable state across threads without data races?
Show answer
Answer: A. Mutex
Rust's `std::sync::Mutex` is the primary primitive for protecting shared mutable data. It ensures that only one thread can access the data at a time, preventing data races. `RwLock` allows multiple readers or one writer. `RefCell` is for interior mutability but is not thread-safe. Atomic types are for simple, lock-free operations on primitive types.
What is the primary mechanism Rust's `Mutex` uses to ensure mutual exclusion?
Show answer
Answer: A. Operating system primitives (e.g., futex on Linux)
Rust's standard library `Mutex` typically relies on underlying operating system primitives (like `futex` on Linux, `Windows Mutex` on Windows) to efficiently manage thread blocking and waking. This is more efficient than pure busy-waiting or spinlocks, which consume CPU cycles unnecessarily.
Which method is used to create a channel that supports multiple producers and multiple consumers in Rust?
Show answer
Answer: A. `crossbeam_channel::unbounded()`
While `std::sync::mpsc` is Multiple Producer Single Consumer, the `crossbeam-channel` crate provides more flexible channel types. `crossbeam_channel::unbounded()` can create channels that support multiple producers and multiple consumers. `std::sync::mpsc::channel()` is MPSC, and `sync_channel` has a bound on the number of messages.
What does the `TryLockError` indicate when returned by a `try_lock()` method on a `Mutex` or `RwLock`?
Show answer
Answer: A. The lock could not be acquired immediately because another thread holds it.
`try_lock()` attempts to acquire a lock without blocking. If the lock is already held by another thread, it returns a `TryLockError` (or similar) indicating that the lock is currently unavailable. It does not imply poisoning or successful acquisition.
What is the purpose of the `SendSync` type alias in the `atomix` crate (or similar concepts)?
Show answer
Answer: A. To represent types that are both `Send` and `Sync`.
A `SendSync` type alias or trait bound is a common convention in Rust concurrency to explicitly state that a type must be safe to send to another thread (`Send`) and safe to share via immutable references across threads (`Sync`).
More questions in this quiz
Answers and explanations are in the full quiz.
- Which Rust type provides exclusive access to a resource, preventing other threads from accessing it while held?
- What does the `Send` trait in Rust signify regarding data that can be transferred between threads?
- If a type `T` implements `Sync`, what does this imply about its usage with shared references (`&T`) across threads?
- What is the purpose of `std::thread::spawn` in Rust?
- Consider a scenario where multiple threads need to read data concurrently but only one thread can write at a time. Which Rust primitive is most suitable for this?
- What does `Arc<T>` allow you to do in Rust concurrency?
- Which of the following guarantees that data is safe to be sent across thread boundaries in Rust?
- What is a common pattern in Rust for communicating between threads without shared mutable state?
- Which type is primarily used for thread-local storage in Rust?
- When using `std::thread::spawn`, what is the return type that allows you to wait for the thread to complete?
- If a type is `Send` but not `Sync`, what can you safely do with it across threads?
- What is the potential problem of using raw pointers (`*const T`, `*mut T`) in concurrent Rust code without proper synchronization?
- Which of the following is NOT a common synchronization primitive provided by Rust's standard library for concurrency?
- What does `crossbeam-channel` offer over `std::sync::mpsc`?
- Consider this code snippet: `let data = Arc::new(Mutex::new(0)); let data_clone = Arc::clone(&data); thread::spawn(move || { let mut num = data_clone.lock().unwrap(); *num += 1; });`. What does `Arc::clone(&data)` achieve?
- What is a 'deadlock' in the context of concurrent programming?
- Which Rust feature helps prevent deadlocks by ensuring that locks are always acquired in a consistent order?
- What is the purpose of the `Send + Sync` trait bounds when defining generic functions or types that interact with threads?
- What is `std::sync::Condvar` used for in Rust concurrency?
- When using `std::sync::Mutex<T>`, what happens if a thread holding the lock panics?
- What is the purpose of the `AtomicBool` type in Rust?
- When using `Arc<Mutex<T>>`, what is the typical pattern for accessing and modifying the data `T`?
- What does the `std::sync::Barrier` primitive do?
- If you need to share data between threads and modify it, but you also need to ensure that the data is not `Sync` (e.g., it contains interior mutability that is not thread-safe), what is a common approach in Rust?
- What is 'thread starvation' in concurrent programming?
- Which type in Rust's standard library provides a bounded, synchronous channel, meaning it has a limited capacity and sending will block if the channel is full?
- What is the primary purpose of `std::thread::JoinHandle::join()`?
- What guarantees does `std::sync::atomic` types provide?
- Consider two threads, T1 and T2, both needing to access resources R1 and R2, protected by Mutexes M1 and M2 respectively. If T1 locks M1 then tries to lock M2, and T2 locks M2 then tries to lock M1, what is the most likely outcome?
- What is the primary benefit of using channels over shared mutable state with mutexes for inter-thread communication in many Rust scenarios?
- If a function is marked `unsafe fn`, what does this imply about its concurrent usage?
- What is the role of `std::sync::Once` or `std::sync::OnceLock` in concurrent Rust?
- When using `std::thread::scope`, what is the primary advantage over `std::thread::spawn`?
- What is a 'spurious wakeup' in the context of condition variables (`Condvar`)?
- Which construct is best suited for implementing a thread pool in Rust?
- What is the primary difference between `Mutex::lock` and `Mutex::try_lock`?
- What does the `Send` trait bound ensure for a type `T` that you want to move into a closure used with `thread::spawn`?
- Which type is used to create a blocking, synchronous, MPSC (Multiple Producer, Single Consumer) channel in Rust's standard library?
- What is the fundamental difference in safety guarantees between `std::sync::Mutex<T>` and `&mut T` when accessed by multiple threads?
- What does the `Relaxed` ordering in `std::sync::atomic` operations guarantee?
- What is a key advantage of using `async/await` for concurrency in Rust compared to OS threads for I/O-bound tasks?
- In the context of `async` Rust, what is a `Stream`?
- What is the purpose of `tokio::sync::Mutex` compared to `std::sync::Mutex`?
- What is a common pattern for managing shared, mutable state across multiple asynchronous tasks in Rust?
- Which method on a `tokio::sync::mpsc::Receiver` allows you to receive a message without blocking the current async task if no message is available?
- What is the primary role of the `JoinHandle::abort()` method in Rust's threading?
- What does `tokio::sync::Notify` provide for asynchronous coordination?
- If a Rust program uses `std::thread::spawn` and the main thread exits before the spawned threads finish, what happens to the spawned threads?
- What is the purpose of the `thread_local!` macro in Rust?
- Consider using `Arc<RwLock<T>>`. What is the primary advantage of `RwLock` over `Mutex` in scenarios with many readers and few writers?