MST

星途 面试题库

面试题:Rust中如何通过原子操作实现ID分配的唯一性基础理解

在Rust中,原子类型 `AtomicUsize` 常被用于实现ID分配。请解释 `AtomicUsize` 如何保证多线程环境下ID分配的原子性,并且给出一个简单示例代码,展示如何利用 `AtomicUsize` 为每个线程分配唯一ID。
29.0万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. AtomicUsize 保证原子性的原理
    • AtomicUsize 是Rust标准库中提供的原子类型,它基于底层硬件提供的原子操作指令(如x86架构上的 lock 前缀指令等)。这些原子操作指令确保对 AtomicUsize 类型变量的读、写和修改操作是不可分割的,在多线程环境下不会出现数据竞争。例如,当一个线程对 AtomicUsize 进行自增操作时,硬件层面会保证这个操作在执行过程中不会被其他线程打断,从而保证了ID分配的原子性。
  2. 示例代码
use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
use std::thread;

fn main() {
    let counter = Arc::new(AtomicUsize::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter_clone = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let id = counter_clone.fetch_add(1, Ordering::SeqCst);
            println!("Thread got ID: {}", id);
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }
}

在上述代码中:

  • 首先创建了一个 AtomicUsize 类型的 counter,初始值为0。
  • 然后通过 thread::spawn 创建10个线程,在每个线程中使用 fetch_add 方法对 counter 进行自增操作并获取当前值作为线程的唯一ID。fetch_add 方法会以原子方式增加 AtomicUsize 的值,并返回增加前的值。
  • Ordering::SeqCst 是一种内存序,它提供了最强的同步保证,确保所有线程都以相同的顺序观察到对原子变量的修改。
  • 最后通过 join 等待所有线程完成。