记录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"

代码

rust 复制代码
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 执行结果

sh 复制代码
cargo run

2. 解决方案

2.1 如果task不依赖其他组件

因业务上tokio的spawn的task可以移除lock且能够独立,故将变量以move的形式实现。

2.2 如果task有依赖

暂没思路

3. 经验

  1. 在multi thread编程中,尽量使用纯函数,不要过多依赖全局变量
  2. 如果有依赖尽量使用dag这样的框架,而不是手写依赖
相关推荐
lzhdim5 小时前
AI的分类
人工智能·算法·机器学习·分类·数据挖掘
凤凰院凶涛QAQ8 小时前
《Java版数据结构 & 集合类剖析》Map & Set & 反射:“从哈希碰撞到红黑树转换,反射帮你扒开 HashMap 的桶数组看个究竟”
java·数据结构·算法
w_zero_one10 小时前
算法--模拟
java·数据结构·算法
小灰灰搞电子10 小时前
Rust+Slint 实现FTP客户端调试助手源码分享
开发语言·后端·rust
秋天的怀念_David10 小时前
算法一千零一夜 · 第十三夜 幻方,武侠世界里的数学迷宫
java·程序人生·算法
秋天的怀念_David11 小时前
算法一千零一夜 · 第十四夜 幻方与奇妙的二进制
java·程序人生·算法
Flynt11 小时前
Cloudflare 用 Rust 重写了 TypeScript:我拿同一批代码跑了跑,报错一模一样,退出码不一样
rust·typescript·前端工程化
薛定e的猫咪11 小时前
(ICLR 2020)MAML 靠的不是快速学习,而是特征复用
人工智能·深度学习·学习·算法·机器学习
薛定e的猫咪12 小时前
(ICLR 2026)DF-META:面向 FJSP 的无导数元学习实例自适应调度
人工智能·深度学习·学习·算法·机器学习
小羊没烦恼!13 小时前
异步编程:线程概述及使用
java·开发语言·mysql·算法·c#