DEV Community

Rust Concurrency Explained: A Beginner's Guide to Arc and Mutex

Iñigo Etxaniz on November 17, 2023

Introduction Jumping into Rust programming has been quite a ride. At first, it felt a bit like trying to solve a puzzle, especially when...
Collapse
 
rami_jiubbe_11bf9508fdd5e profile image
Rami Jiubbe

An amazing article! I really enjoyed it.

I just have one question. Could the following scenario lead to a deadlock?

  • Thread 1 acquires the count, count_thread1, and write_lock.
  • Thread 1 then releases count and count_thread1 by calling drop.
  • Thread 2 acquires the count and count_thread2, and waits for Thread 1 to release the write_lock.
  • Meanwhile, Thread 1 tries to acquire the count lock again for reading.

In this case, it seems like Thread 2 is waiting for Thread 1 to release the write_lock, while Thread 1 is waiting to acquire the count lock, resulting in a deadlock.

Am I correct, or did I miss something?

Collapse
 
ietxaniz profile image
Iñigo Etxaniz

Good point Rami,

I drop count and count_thread1 explicitly so that I can safely call get_counts.

Rust automatically releases all locks when they go out of scope at the end of the function, so I don't need to manually drop write_lock.

Collapse
 
rami_jiubbe_11bf9508fdd5e profile image
Rami Jiubbe

The write_lock goes out of scope when the thread1 function completes its execution. What I'm saying is that the get_count function is called within thread1, meaning the write_lock won't be released during the get_count call. Is that correct? Additionally, it's inside get_count where thread1 attempts to reacquire the count lock for reading.

Thread Thread
 
ietxaniz profile image
Iñigo Etxaniz

Uhmm, I think now I understand the possibility of a deadlock... lets imagine next sequence...

  • thread1: lock count
  • thread1: lock count_thread1
  • thread1: lock write_lock
  • thread1: release count
  • thread2: lock count
  • thread2: lock count_thread2
  • thread2: lock write_lock (**waiting here*)
  • thread1: release count_thread1
  • thread1: lock count inside get_counts (waiting here)

Is this what you mean? A possible solution would be to start both thread calls locking write_lock in the first place, this would prevent thread2 from locking count till write_lock is released in thread1.

Thread Thread
 
rami_jiubbe_11bf9508fdd5e profile image
Rami Jiubbe

That's exactly what I meant. I just wanted to mention that I asked the question because I had a small doubt I hoped to clear up by discussing the bug with you. Thanks again for this fantastic article, and have a great day!

Collapse
 
isaacdlyman profile image
Isaac Lyman

This is an excellent article. Thank you.

One question: If RwLock is better than Mutex even in a situation like this where you aren’t doing concurrent reads, when would you use Mutex?

Collapse
 
ietxaniz profile image
Iñigo Etxaniz

You are absolutely right. In this concrete scenario Mutex would be better as we are not doing any concurrent reads. The thing is that I consider this simple example as the building block of more general or complex use cases and by default I usually use read-write locks without thinking too much on it.

Collapse
 
isaacdlyman profile image
Isaac Lyman

Are there any advantages to Mutex, then? Does it use less memory or make deadlocks easier to catch?

Thread Thread
 
ietxaniz profile image
Iñigo Etxaniz • Edited

Don't know about that, but I guess it will be more efficient as it has less things to check... The thing is that only one thread will have access to data when using mutex while it is locked, whilst using RwLock many reads can be done simultaneously. So RwLock has to check if it is write or read lock and what kind of current lock exists.

Collapse
 
judevector profile image
Jude Ndubuisi 🥷🧑‍💻

As someone who just started his Rust learning journey, I love this article. This will help me understand this awesome language alot, am already loving it 😊

Collapse
 
ietxaniz profile image
Iñigo Etxaniz

Hi Jude,

Thanks for your kind words! It's great to hear you're finding the article helpful as we both navigate the exciting journey of learning Rust. Rust can be quite unique at first, but it's a rewarding experience. Let's keep learning together!