Explore fundamental concepts of concurrency in Rust, including thread management, mutex usage, and message passing with channels. This quiz helps you assess your understanding of safe and efficient parallel programming techniques in Rust.
Which function do you use to create a new thread for concurrent execution in Rust?
Explanation: The correct answer is thread::spawn, which is the standard function in Rust used to create a new thread. thread::launch, std::go, and spawn_thread are not valid Rust functions for thread creation. The others might look plausible or similar to names from other languages, but only thread::spawn is defined in the Rust standard library for this purpose.
What is the primary purpose of using a Mutex in Rust concurrency?
Explanation: A Mutex is used to ensure that only one thread can access shared mutable data at a time, preventing data races. Increasing execution speed of a single thread is unrelated to a mutex's functionality. Mutexes are not used for immutable access or for message passing; those are handled differently, such as through channels for the latter.
What does calling the join() method on a thread handle do in Rust?
Explanation: The join() method waits for the associated thread to complete, blocking the caller until it's done. It does not start or terminate a thread, nor does it merge code from different threads. Only the correct answer accurately describes the behavior of join in Rust's threading model.
Which keyword is required to move ownership of a variable into a spawned thread's closure in Rust?
Explanation: The move keyword is necessary to transfer ownership of captured values into the closure provided to thread::spawn. clone creates a copy but doesn't move ownership, mut is for mutability, and let is for variable binding, not for moving variables into closures.
What does the lock() method on a Mutex return in Rust?
Explanation: lock() returns a MutexGuard, which grants temporary access to the protected data while managing the lock's lifecycle. It does not return a boolean, the unwrapped data, or a static reference. Only the guard manages the safe, temporary access around the mutex.
In Rust, what is the role of the channel's sender in multi-threaded communication?
Explanation: A channel's sender transmits values to its corresponding receiver, which can then be used in another thread. Receiving values is the receiver's job. Channels do not perform data locking or spawn new threads, so the other answers are incorrect.
Which combination is commonly used in Rust to allow multiple threads to mutate shared data?
Explanation: Arcu003CMutexu003CTu003Eu003E combines atomic reference counting with mutual exclusion, making it safe and practical for shared, mutable data across threads. Rcu003CCellu003CTu003Eu003E isn't thread-safe, RefCellu003CArcu003CTu003Eu003E does not provide interior mutability across threads, and Mutexu003CRefu003CTu003Eu003E is invalid as Ref cannot be standalone.
For a type to be passed between threads in Rust, which trait must it implement?
Explanation: The Send trait marks types that can be transferred safely between threads. Sized ensures compile-time sizing, Drop is for custom cleanup, while Copy is for bitwise duplication but not related specifically to multithreading.
Which function in Rust's standard library creates a new channel for message passing?
Explanation: mpsc::channel initializes a multi-producer, single-consumer channel in Rust, used commonly for thread communication. The other options resemble possible functions but do not exist in Rust's standard library.
What can cause a deadlock when using Mutexes in multiple threads in Rust?
Explanation: A classic deadlock occurs when two threads each hold one mutex and wait for the other’s mutex, blocking indefinitely. The number of CPU cores doesn't create deadlocks, implementing Clone for Mutex is restricted to avoid misuse, and immutable references won't cause deadlocks since no locking is needed with them.