记录rust滥用lazy_static导致的一个bug
记录rust滥用lazy_static导致的一个bug
本质就是lock以后task crash
后导致其他线程饿死;在cpp20的coroutine也有类似场景
1. 模拟代码
toml
[package]
name = "rust-crash-collect-20250611"
version = "0.1.0"
edition = "2024"[dependencies]
tokio = { version = "1.40.0", features = ["full"] }
lazy_static = "1.5.0"
代码
use std::sync::Mutex;lazy_static::lazy_static! {static ref COUNTER: Mutex<i32> = Mutex::new(0);
}struct raii {name: String,
}impl Drop for raii {fn drop(&mut self) {println!("Dropping raii");}
}#[tokio::main]
async fn main() {for cnt in 0..10 {tokio::spawn(async move {let raii = raii {name: format!("raii {}", cnt),};let mut counter = COUNTER.lock();match counter {Ok(mut counter) => {*counter += 1;println!("counter: {}", *counter);if *counter == 5 {panic!("Counter is 5");}}Err(e) => {println!("Error: {}", e);}}});}loop {}
}
1.1 执行结果
cargo run
2. 解决方案
2.1 如果task不依赖其他组件
因业务上tokio
的spawn
的task
可以移除lock
且能够独立,故将变量以move
的形式实现。
2.2 如果task有依赖
暂没思路
3. 经验
- 在multi thread编程中,尽量使用纯函数,不要过多依赖全局变量
- 如果有依赖尽量使用dag这样的框架,而不是手写依赖