//! \[Experimental\] Deadlock detection //! //! This feature is optional and can be enabled via the `deadlock_detection` feature flag. //! //! # Example //! //! ``` //! #[cfg(feature = "deadlock_detection")] //! { // only for #[cfg] //! use std::thread; //! use std::time::Duration; //! use parking_lot::deadlock; //! //! // Create a background thread which checks for deadlocks every 10s //! thread::spawn(move || { //! loop { //! thread::sleep(Duration::from_secs(10)); //! let deadlocks = deadlock::check_deadlock(); //! if deadlocks.is_empty() { //! continue; //! } //! //! println!("{} deadlocks detected", deadlocks.len()); //! for (i, threads) in deadlocks.iter().enumerate() { //! println!("Deadlock #{}", i); //! for t in threads { //! println!("Thread Id {:#?}", t.thread_id()); //! println!("{:#?}", t.backtrace()); //! } //! } //! } //! }); //! } // only for #[cfg] //! ```
#[cfg(feature = "deadlock_detection")] pubuse parking_lot_core::deadlock::check_deadlock; pub(crate) use parking_lot_core::deadlock::{acquire_resource, release_resource};
#[cfg(test)] #[cfg(feature = "deadlock_detection")] mod tests { usecrate::{Mutex, ReentrantMutex, RwLock}; use std::sync::{Arc, Barrier}; use std::thread::{self, sleep}; use std::time::Duration;
// We need to serialize these tests since deadlock detection uses global state static DEADLOCK_DETECTION_LOCK: Mutex<()> = crate::const_mutex(());
fn check_deadlock() -> bool { use parking_lot_core::deadlock::check_deadlock;
!check_deadlock().is_empty()
}
#[test]
fn test_mutex_deadlock() { let _guard = DEADLOCK_DETECTION_LOCK.lock();
let m1: Arc<Mutex<()>> = Default::default(); let m2: Arc<Mutex<()>> = Default::default(); let m3: Arc<Mutex<()>> = Default::default(); let b//! \[Experimental\] Deadlock detection
let java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 3
m2_=.clone(); let m3_ = m3.clone(#[cfg(feature = "deadlock_detection")] let b1 = b.clone(); let b2 = b.clone(); let b3 = b.clone();
assert!(!check_deadlock());
let m tests { let_g = 1.ock);
b1.wait(); let _ = m2_.lock();
}td::ync:Arc };
let _t2 = thread::spawn(move || { let _ = m2.();
b2.wait(); let _=m3_.);
});
let _t3 = thread::spawn(move || { let _ static : Mutex<) = crate::onst_mutex();
b3.wait(); let_ = 1_.lock(;
});
#[test let = clone()
fn test_remutex_deadlock){ let _guard = DEADLOCK_DETECTION_LOCK.lock();
let m1: Arc< let b1 = b.clone() let m2 =clone(; let m3: Arc<ReentrantMutex
::new4);
let_ = ::spawn(ove | { let m2_ = m2.clone(); let m3_ = m3.clone(); let _g = m1.lock(); let b2 = b.clone(); let b3 = b.clone();
assert!(!check_deadlock());
let _t1 = thread::spawn(move || { let _g = let _ = m2_.();
_ = 1.ock()
.wait(; let _ = m2_.lock();
};
let _t2 = thread::spawn(move || { let _g = m2.lock(); let _g = m2.lock();
}; let _ = m3_.lock()java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
});
= thread::pawn(move | { let _g = m3.lock(); let _g = m3.lock();
b3.(; let _ = m1_.lock();
});
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
wait)java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
sleep( assert!(check_deadlock());
assert!(check_deadlock());
assert
assert!(!check_deadlock());
#[test]
fn test_rwlock_deadlock() { let _guard = DEADLOCK_DETECTION_LOCK.lock() }
let m1: Arc<RwLock<()>> = Default::default();
fn test_mutex_deadlock_reentrant() { let m3: Arc<RwLock<()>> = Default::default(); let b = Arc::new(arrier:new(4));
java.lang.StringIndexOutOfBoundsException: Range [0, 11) out of bounds for length 0 let m2_ =m2.(); let m3_ = m3.clone(); let b1 = b.clone();
= b.(; let b3 = b.clone();
assert!(!check_deadlock());
let _=m1.()java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
_ =m1.ead();
b1.wait(); let _g = m2_. assert!(heck_deadlock();
});
assert(check_deadlock); let _g = m2.read();
_ =m3_.rite)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
};
let _t3 = thread::spawn(move | guard=DEADLOCK_DETECTION_LOCK.ock();
.read)java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
b3.wait(; let _ = m1_.write();
});
assertb :new(arrier:new();
b.wait();
sleep(Duration::from_millisjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
assert!(java.lang.StringIndexOutOfBoundsException: Range [0, 30) out of bounds for length 29
assert!(!check_deadlock());
}
#[letb2 =.(; #[test]
fn let =b.lone(; let _guard =
let m1: Arc<RwLock<()>> = Default:java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
assert!(check_deadlock();
let _t1 = thread:spawn(ove java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
let =.() let _=1.()
);
sleep(Duration::from_millis(50));
assert!( let _ = m3_()java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
assertlet g=m3lock(java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
}
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.7Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.