MST

星途 面试题库

面试题:Rust if表达式在并发控制流中的精妙应用

在一个多线程的Rust程序中,有多个线程在同时访问和修改一个共享的计数器变量`counter`。主线程需要根据`counter`的值来决定是否终止所有线程。当`counter`达到100时,主线程要通知所有子线程停止工作(可以使用`mpsc`通道来实现通知),并且主线程在所有子线程停止后打印"所有线程已停止"。请使用if表达式合理构建这个并发控制流逻辑,要求代码正确处理同步和通信问题,保证程序的健壮性。请写出完整代码及对关键控制流部分的详细解释。
44.3万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
use std::sync::{Arc, Mutex};
use std::thread;
use std::sync::mpsc::{channel, Receiver, Sender};

fn main() {
    let counter = Arc::new(Mutex::new(0));
    let (tx, rx): (Sender<()>, Receiver<()>) = channel();

    let mut handles = Vec::new();
    for _ in 0..10 {
        let counter_clone = Arc::clone(&counter);
        let tx_clone = tx.clone();
        let handle = thread::spawn(move || {
            loop {
                let mut num = counter_clone.lock().unwrap();
                *num += 1;
                println!("子线程增加counter到: {}", *num);
                if *num >= 100 {
                    tx_clone.send(()).unwrap();
                    break;
                }
            }
        });
        handles.push(handle);
    }

    if let Ok(_) = rx.recv() {
        for handle in handles {
            handle.join().unwrap();
        }
        println!("所有线程已停止");
    }
}

关键控制流部分详细解释:

  1. 共享计数器
    • 使用Arc<Mutex<i32>>来创建一个可在多线程间共享且线程安全的计数器counterArc(原子引用计数)允许在多个线程间共享数据,Mutex(互斥锁)用于保护数据,确保同一时间只有一个线程可以访问和修改计数器。
  2. 通道创建
    • 使用mpsc::channel()创建一个通道(tx, rx)tx(发送者)用于子线程向主线程发送通知,rx(接收者)用于主线程接收通知。
  3. 子线程逻辑
    • 在每个子线程中,通过counter_clone.lock().unwrap()获取锁来修改计数器的值。
    • 使用if *num >= 100判断计数器是否达到100,如果达到则通过tx_clone.send(()).unwrap()向主线程发送通知,并通过break跳出循环停止子线程工作。
  4. 主线程逻辑
    • 使用if let Ok(_) = rx.recv()等待接收子线程发送的通知。当接收到通知后,遍历所有子线程的handle,通过handle.join().unwrap()等待所有子线程结束,最后打印"所有线程已停止"。这样确保了主线程在所有子线程停止后才执行打印操作。