A Mutex (short for mutual exclusion) is a tool that allows only one thread to access a shared resource at a time, preventing conflicts and data corruption.
Click to reveal answer
beginner
How do you create a Mutex in Ruby?
You create a Mutex by calling Mutex.new. For example: mutex = Mutex.new
Click to reveal answer
beginner
What does the mutex.synchronize method do?
It locks the mutex before running the code block and unlocks it after the block finishes, ensuring only one thread runs that code at a time.
Click to reveal answer
beginner
Why is thread synchronization important when using shared variables?
Without synchronization, multiple threads can change shared variables at the same time, causing unpredictable results or errors.
Click to reveal answer
intermediate
What happens if you forget to unlock a Mutex?
Other threads waiting for the lock will be blocked forever, causing your program to freeze or deadlock.
Click to reveal answer
What is the main purpose of a Mutex in Ruby threading?
ATo prevent multiple threads from accessing shared data at the same time
BTo allow multiple threads to run code simultaneously
CTo speed up thread execution
DTo create new threads automatically
✗ Incorrect
A Mutex ensures that only one thread accesses shared data at a time to avoid conflicts.
Which Ruby method locks and unlocks a Mutex automatically around a block of code?
Amutex.lock
Bmutex.synchronize
Cmutex.unlock
Dmutex.wait
✗ Incorrect
mutex.synchronize locks the mutex before the block and unlocks it after.
What could happen if two threads modify a shared variable without a Mutex?
AThe program runs faster
BThe variable keeps its original value
CData corruption or unpredictable results
DThreads automatically synchronize
✗ Incorrect
Without synchronization, simultaneous access can corrupt data or cause errors.
How do you create a new Mutex in Ruby?
AMutex.new
BMutex.create
CThread.new
DMutex.start
✗ Incorrect
You create a Mutex by calling Mutex.new.
What is a deadlock in the context of Mutex?
AWhen a thread finishes execution
BWhen multiple threads run without synchronization
CWhen a Mutex is unlocked too early
DWhen threads wait forever because a Mutex is never unlocked
✗ Incorrect
Deadlock happens when threads wait forever because a Mutex is not released.
Explain how a Mutex helps with thread synchronization in Ruby.
Think about how to keep shared data safe when many threads run.
You got /4 concepts.
Describe what can go wrong if you do not use a Mutex when multiple threads access shared variables.
Imagine two people writing on the same paper at the same time.
You got /4 concepts.
Practice
(1/5)
1. What is the main purpose of using a Mutex in Ruby threads?
easy
A. To create new threads automatically
B. To prevent multiple threads from accessing shared data at the same time
C. To speed up thread execution by running them in parallel
D. To stop threads from running
Solution
Step 1: Understand what shared data means in threads
Shared data is information that multiple threads can access or change.
Step 2: Identify the role of Mutex
Mutex ensures only one thread changes shared data at a time to avoid errors.
Final Answer:
To prevent multiple threads from accessing shared data at the same time -> Option B
Quick Check:
Mutex protects shared data = prevent simultaneous access [OK]
Hint: Mutex locks shared data to avoid conflicts between threads [OK]
Common Mistakes:
Thinking Mutex speeds up threads
Believing Mutex creates threads
Assuming Mutex stops threads completely
2. Which of the following is the correct way to use a Mutex to protect a critical section in Ruby?
easy
A. mutex.synchronize { critical_code }
B. mutex.lock; critical_code
C. mutex.run(critical_code)
D. mutex.start { critical_code }
Solution
Step 1: Recall Mutex usage in Ruby
Ruby's Mutex class provides a synchronize method to wrap critical code safely.
Step 2: Compare options
Only mutex.synchronize { critical_code } is the correct and safe syntax.
Final Answer:
mutex.synchronize { critical_code } -> Option A
Quick Check:
Use synchronize method to protect code [OK]
Hint: Use mutex.synchronize { } to wrap critical code [OK]
Common Mistakes:
Forgetting to unlock mutex after lock
Using non-existent methods like run or start
Not wrapping critical code in a block
3. What will be the output of this Ruby code?
require 'thread'
mutex = Mutex.new
counter = 0
threads = 3.times.map do
Thread.new do
2.times do
mutex.synchronize { counter += 1 }
end
end
end
threads.each(&:join)
puts counter
medium
A. 2
B. 3
C. 6
D. 0
Solution
Step 1: Count total increments
There are 3 threads, each increments counter 2 times, total 3*2=6 increments.
Step 2: Understand mutex effect
Mutex ensures increments happen safely without losing counts, so final counter is 6.
Final Answer:
6 -> Option C
Quick Check:
3 threads * 2 increments each = 6 [OK]
Hint: Multiply threads by increments inside synchronize block [OK]
Common Mistakes:
Ignoring mutex and expecting wrong count
Counting only one thread's increments
Confusing thread join effect
4. Identify the problem in this Ruby code using Mutex and how to fix it:
require 'thread'
mutex = Mutex.new
counter = 0
threads = 2.times.map do
Thread.new do
mutex.lock
counter += 1
end
end
threads.each(&:join)
puts counter
medium
A. Threads are not joined properly; fix by joining inside the thread block
B. Mutex is not needed here; remove mutex.lock
C. counter should be initialized inside the thread
D. Missing mutex.unlock causes deadlock; fix by adding mutex.unlock after increment
Solution
Step 1: Check mutex usage
Mutex is locked but never unlocked, causing threads to wait forever (deadlock).
Step 2: Fix by unlocking mutex
After increment, call mutex.unlock or better use mutex.synchronize to auto-handle locking/unlocking.
Final Answer:
Missing mutex.unlock causes deadlock; fix by adding mutex.unlock after increment -> Option D
Quick Check:
Always unlock mutex after lock to avoid deadlock [OK]
Hint: Always unlock mutex or use synchronize block [OK]
Common Mistakes:
Forgetting to unlock mutex
Removing mutex when needed
Initializing shared data inside threads incorrectly
5. You want to safely update a shared hash from multiple threads in Ruby. Which approach correctly uses Mutex to avoid race conditions?
shared_hash = {}
mutex = Mutex.new
threads = 5.times.map do |i|
Thread.new do
10.times do |j|
# What goes here?
end
end
end
threads.each(&:join)
puts shared_hash.size