You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust多线程读写变量问题:超市队列模拟程序异常排查

Rust超市队列并发问题的修复

你的问题核心是第一个线程一直持有Mutex锁,导致第二个线程完全无法获取锁执行代码。

问题原因

第一个线程里,aux是MutexGuard类型,它的作用域覆盖了整个loop迭代——从调用lock()开始,直到thread::sleep(3秒)结束、整个循环块执行完毕,锁才会被释放。而Mutex是独占锁,第二个线程会一直卡在queue.lock()这一步,根本没机会进入后续逻辑,自然打不出"AUX state"的日志。

Rust的MutexGuard是RAII机制实现的,只有当它离开当前作用域时,才会自动调用drop释放锁。你原来的代码里,sleep是在锁持有期间执行的,这完全没必要,还会导致锁被长时间占用。

修复代码

把锁的持有范围缩小到仅操作队列的阶段,用一对额外的大括号限制aux的作用域,让锁在sleep前就释放:

use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use rand::Rng;

fn print_queue(queue: &Vec<char>) {
    println!("Queue: {:?}", queue);
}

fn main() {
    let queue = Arc::new(Mutex::new(Vec::<char>::new()));

    let queue1 = Arc::clone(&queue);
    thread::spawn(move || loop {
        // 用大括号缩小锁的作用域
        {
            let mut aux = queue1.lock().unwrap();
            aux.push('x');
            print_queue(&aux);
        } // 这里aux离开作用域,锁被自动释放
        thread::sleep(Duration::from_secs(3));
    });

    let queue2 = Arc::clone(&queue);
    thread::spawn(move || loop {
        {
            let mut aux = queue2.lock().unwrap();
            println!("AUX state: {:?}", aux);
            if !aux.is_empty() {
                aux.pop();
            }
            print_queue(&aux);
        } // 锁在这里释放
        let mut rng = rand::thread_rng();
        thread::sleep(Duration::from_secs(rng.gen_range(1..10)));
    });

    // 主线程需保持运行,否则子线程会被强制终止
    thread::sleep(Duration::from_secs(30));
}

额外注意点

  1. 第二个线程建议单独clone一份Arc实例,避免后续可能出现的所有权混淆问题;
  2. 主线程必须添加足够长的sleep逻辑,否则主线程退出后所有子线程会被立即终止,无法看到完整的并发执行效果。

内容的提问来源于stack exchange,提问作者Erik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 15:55:19