MST

星途 面试题库

面试题:Rust多线程进度报告中原子操作的基本实现

在Rust多线程环境下实现进度报告,要求使用原子操作来保证数据的一致性。假设你有一个表示任务进度的变量,线程会不断更新这个进度,主线程需要定期读取进度并打印。请描述你会使用哪些原子类型以及如何实现这个功能。
27.5万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. 选择原子类型

    • 在Rust中,可以使用std::sync::atomic::AtomicU32来表示任务进度。AtomicU32是一个用于32位无符号整数的原子类型,适合表示进度百分比等数值。
  2. 实现步骤

    • 引入必要的库
      use std::sync::{Arc, atomic::{AtomicU32, Ordering}};
      use std::thread;
      
    • 创建原子变量
      let progress = Arc::new(AtomicU32::new(0));
      
    • 创建工作线程
      let progress_clone = Arc::clone(&progress);
      let handle = thread::spawn(move || {
          for i in 0..100 {
              progress_clone.store(i, Ordering::SeqCst);
              thread::sleep(std::time::Duration::from_millis(100));
          }
      });
      
    • 主线程定期读取进度并打印
      loop {
          let current_progress = progress.load(Ordering::SeqCst);
          println!("Current progress: {}%", current_progress);
          if current_progress == 100 {
              break;
          }
          thread::sleep(std::time::Duration::from_secs(1));
      }
      
    • 等待工作线程结束
      handle.join().unwrap();
      

整个示例代码如下:

use std::sync::{Arc, atomic::{AtomicU32, Ordering}};
use std::thread;

fn main() {
    let progress = Arc::new(AtomicU32::new(0));
    let progress_clone = Arc::clone(&progress);
    let handle = thread::spawn(move || {
        for i in 0..100 {
            progress_clone.store(i, Ordering::SeqCst);
            thread::sleep(std::time::Duration::from_millis(100));
        }
    });

    loop {
        let current_progress = progress.load(Ordering::SeqCst);
        println!("Current progress: {}%", current_progress);
        if current_progress == 100 {
            break;
        }
        thread::sleep(std::time::Duration::from_secs(1));
    }

    handle.join().unwrap();
}

在上述代码中:

  • AtomicU32store方法用于更新进度值,load方法用于读取进度值。
  • Ordering::SeqCst是一种较强的内存序,确保对原子变量的读写操作以一种全局一致的顺序发生,保证数据一致性。