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 打开数据库性能低,与事务回滚