[Day12] Read Rust Atomics and Locks — Lock Poisoning

by Mara Bos

R4 Cheng
2 min readMay 31, 2023

At Topics: Chapter 1. Basics of Rust Concurrency

Until: Lifetime of the MutexGuard

Sync to My Blog: https://my-blog-chengr4.vercel.app/posts/day12-read-rust-atomics-and-locks-lock-poisoning_230531

Notes

Lock Poisoning

A Mutex in Rust gets marked as poisoned when a thread panics while holding the lock. When that happens, the Mutex will no longer be locked, but calling its lock method will result in an Err to indicate it has been poisoned.

Why we need to mark the mutex as poisoned?

If we do not do so, it may break assumptions made by other threads (Generate inconsistent state). By marking the mutex as poisoned, we can be forced to handle inconsistent state.

How it works?

Calling lock() on a poisoned mutex still locks the mutex but also results in an Err. The returned Err contains the MutexGuard, allowing us to correct an inconsistent state if necessary.

Lifetime of the MutexGuard

  • Lock and unlock the mutex in a single statement:
// it is Mutex<Vec<i32>>
// You can lock the mutex, push an item into the Vec, and unlock the mutex again, in a single statement
list.lock().unwrap().push(1);
  • We should be careful of using mutex with match, if let, or while let. Look at the following example:
// Bad one
if let Some(item) = list.lock().unwrap().pop() {
process_item(item); // we still hold on to the lock unnecessarily
} // The temporary guard will be dropped after here

// Good one
let item = list.lock().unwrap().pop(); // guard does get dropped here
if let Some(item) = item {
process_item(item);
}

// Similar one but is ok
// A regular if statement is always a plain boolean, which cannot borrow anything
if list.lock().unwrap().pop() == Some(1) { // guard does get dropped here
do_something();
}

--

--

R4 Cheng
R4 Cheng

Written by R4 Cheng

「0」が過去で「1」が未来「今」は何処にもない

No responses yet