deadlock detection must not run as tokio task

Posted 金庆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了deadlock detection must not run as tokio task相关的知识,希望对你有一定的参考价值。

deadlock detection must not run as tokio task

(Jin Qing’s Column, Feb., 2022)

parking_lot has an experimental feature: deadlock_detection.

See: https://amanieu.github.io/parking_lot/parking_lot/deadlock/index.html

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());
            
        
    
);

The output is like this:

1 deadlocks detected
Deadlock #0
Thread Id 16072
   0:     0x7ff985cb659d - backtrace::backtrace::dbghelp::trace
                               at d:\\Users\\jinqing\\.cargo\\registry\\src\\github.com-1ecc6299db9ec823\\backtrace-0.3.63\\src\\backtrace\\dbghelp.rs:98
...
  13:     0x7ff985ae92f3 - lock_api::rwlock::RwLock<parking_lot::raw_rwlock::RawRwLock,cgc::scene_template::SceneTemplate>::read<parking_lot::raw_rwlock::RawRwLock,cgc::scene_template::SceneTemplate>
                               at d:\\Users\\jinqing\\.cargo\\registry\\src\\github.com-1ecc6299db9ec823\\lock_api-0.4.6\\src\\rwlock.rs:448
  14:     0x7ff985aeadf3 - cgc::scene::SceneData::check_body_collide
                               at E:\\gitlab\\yserver\\gc\\src\\scene.rs:99
...
  81:     0x7ff9f29b7034 - BaseThreadInitThunk
  82:     0x7ff9f2b02651 - RtlUserThreadStart

But the deadlock detection thread can not be changed to a tokio task,
because if deadlock happens, all tasks may be blocked, including the deadlock detection,
causing no deadlock error output.

In the following example, if the number of the deadlock tasks is larger than the thread number of tokio runtime,
all tasks will be blocked.

use std::thread, time::Duration;

use parking_lot::RwLock;
use tokio::time;

#[tokio::main]
async fn main() 
    tokio::spawn(async move 
        for i in 0..999999 
            println!("", i);
            time::sleep(Duration::from_secs(1)).await;
        
    );

    const MAX: i32 = 100;
    for _ in 0..MAX 
        tokio::spawn(async move 
            
                // DEADLOCK!
                let a = RwLock::new(());
                let _g1 = a.write();
                let _g2 = a.write();
            

            time::sleep(Duration::from_secs(9999)).await;
        );
    

    println!("Hello, world!");
    thread::sleep(Duration::from_secs(10));

The output is:

0
Hello, world!
_

If no deadlock, or the number of deadlock tasks is small, the output should be:

0
Hello, world!
1
2
3
...

以上是关于deadlock detection must not run as tokio task的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL innodb_deadlock_detect 打开数据库性能低,与事务回滚

LATEST DETECTED DEADLOCK

记录一次线上 Oracle 数据库 ORA-00060: deadlock detected 故障案例

sql 在最后N分钟获取Deadlock查询

sql 在最后N分钟获取Deadlock查询

UVa10323:Factorial! You Must be Kidding!!!