Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  deadlock.rs

  Sprache: Rust
 

//! \[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")]
pub use parking_lot_core::deadlock::check_deadlock;
pub(crateuse parking_lot_core::deadlock::{acquire_resource, release_resource};

#[cfg(test)]
#[cfg(feature = "deadlock_detection")]
mod tests {
    use crate::{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 = Arc::new(Barrier::new(4));

        let m1_ = m1.clone();
        let m2_ = m2.clone();
        let m3_ = m3.clone();
        let b1 = b.clone();
        let b2 = b.clone();
        let b3 = b.clone();

        assert!(!check_deadlock());

        let _t1 = thread::spawn(move || {
            let _g = m1.lock();
            b1.wait();
            let _ = m2_.lock();
        });

        let _t2 = thread::spawn(move || {
            let _g = m2.lock();
            b2.wait();
            let _ = m3_.lock();
        });

        let _t3 = thread::spawn(move || {
            let _g = m3.lock();
            b3.wait();
            let _ = m1_.lock();
        });

        assert!(!check_deadlock());

        b.wait();
        sleep(Duration::from_millis(50));
        assert!(check_deadlock());

        assert!(!check_deadlock());
    }

    #[test]
    fn test_mutex_deadlock_reentrant() {
        let _guard = DEADLOCK_DETECTION_LOCK.lock();

        let m1: Arc<Mutex<()>> = Default::default();

        assert!(!check_deadlock());

        let _t1 = thread::spawn(move || {
            let _g = m1.lock();
            let _ = m1.lock();
        });

        sleep(Duration::from_millis(50));
        assert!(check_deadlock());

        assert!(!check_deadlock());
    }

    #[test]
    fn test_remutex_deadlock() {
        let _guard = DEADLOCK_DETECTION_LOCK.lock();

        let m1: Arc<ReentrantMutex<()>> = Default::default();
        let m2: Arc<ReentrantMutex<()>> = Default::default();
        let m3: Arc<ReentrantMutex<()>> = Default::default();
        let b = Arc::new(Barrier::new(4));

        let m1_ = m1.clone();
        let m2_ = m2.clone();
        let m3_ = m3.clone();
        let b1 = b.clone();
        let b2 = b.clone();
        let b3 = b.clone();

        assert!(!check_deadlock());

        let _t1 = thread::spawn(move || {
            let _g = m1.lock();
            let _g = m1.lock();
            b1.wait();
            let _ = m2_.lock();
        });

        let _t2 = thread::spawn(move || {
            let _g = m2.lock();
            let _g = m2.lock();
            b2.wait();
            let _ = m3_.lock();
        });

        let _t3 = thread::spawn(move || {
            let _g = m3.lock();
            let _g = m3.lock();
            b3.wait();
            let _ = m1_.lock();
        });

        assert!(!check_deadlock());

        b.wait();
        sleep(Duration::from_millis(50));
        assert!(check_deadlock());

        assert!(!check_deadlock());
    }

    #[test]
    fn test_rwlock_deadlock() {
        let _guard = DEADLOCK_DETECTION_LOCK.lock();

        let m1: Arc<RwLock<()>> = Default::default();
        let m2: Arc<RwLock<()>> = Default::default();
        let m3: Arc<RwLock<()>> = Default::default();
        let b = Arc::new(Barrier::new(4));

        let m1_ = m1.clone();
        let m2_ = m2.clone();
        let m3_ = m3.clone();
        let b1 = b.clone();
        let b2 = b.clone();
        let b3 = b.clone();

        assert!(!check_deadlock());

        let _t1 = thread::spawn(move || {
            let _g = m1.read();
            b1.wait();
            let _g = m2_.write();
        });

        let _t2 = thread::spawn(move || {
            let _g = m2.read();
            b2.wait();
            let _g = m3_.write();
        });

        let _t3 = thread::spawn(move || {
            let _g = m3.read();
            b3.wait();
            let _ = m1_.write();
        });

        assert!(!check_deadlock());

        b.wait();
        sleep(Duration::from_millis(50));
        assert!(check_deadlock());

        assert!(!check_deadlock());
    }

    #[cfg(rwlock_deadlock_detection_not_supported)]
    #[test]
    fn test_rwlock_deadlock_reentrant() {
        let _guard = DEADLOCK_DETECTION_LOCK.lock();

        let m1: Arc<RwLock<()>> = Default::default();

        assert!(!check_deadlock());

        let _t1 = thread::spawn(move || {
            let _g = m1.read();
            let _ = m1.write();
        });

        sleep(Duration::from_millis(50));
        assert!(check_deadlock());

        assert!(!check_deadlock());
    }
}

Messung V0.5 in Prozent
C=83 H=85 G=83

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet am  2026-06-18) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik