1. 创建并运行第一个线程

创建并运行第一个线程 学习卡片

任务说明

本案例的目标是使用 Rust 标准库中的 std::thread::spawn 创建一个子线程,并演示主线程如何等待子线程执行完毕。我们将通过一个最小可复现的示例,展示线程的创建、子线程中任务的执行,以及主线程使用 JoinHandle::join() 进行同步等待的完整流程。

核心实现

use std::thread;
use std::time::Duration;

fn main() {
    // 创建一个子线程,执行闭包中的任务
    let handle = thread::spawn(|| {
        for i in 1..=5 {
            println!("子线程打印: {}", i);
            thread::sleep(Duration::from_millis(100));
        }
    });

    // 主线程执行自己的任务
    for i in 1..=3 {
        println!("主线程打印: {}", i);
        thread::sleep(Duration::from_millis(150));
    }

    // 等待子线程执行完毕
    handle.join().expect("子线程执行失败");

    println!("所有线程执行完毕");
}

代码说明

上述代码中,thread::spawn 接收一个闭包作为参数,闭包内的逻辑将在新创建的子线程中执行。子线程会循环打印 1 到 5,每次打印后休眠 100 毫秒。主线程则循环打印 1 到 3,每次休眠 150 毫秒。主线程在完成自己的打印任务后,调用 handle.join() 阻塞等待子线程结束。由于子线程需要打印 5 次(总耗时约 500ms),而主线程只需打印 3 次(总耗时约 450ms),因此 join() 会确保主线程等待子线程完成剩余的工作。

线程执行时序

线程执行时序图 时间 主线程 子线程 打印 1~3 (450ms) 打印 1~5 (500ms) join() 阻塞等待 子线程结束 继续执行并退出

编译与运行

确保已安装 Rust 工具链(包含 cargo)。在项目目录下创建 src/main.rs 并粘贴上述代码,然后在终端执行:

cargo run

验证方法与判定标准

运行程序后,观察终端输出。判定标准如下:

  • 输出中应包含“主线程打印: 1”至“主线程打印: 3”以及“子线程打印: 1”至“子线程打印: 5”的全部内容;
  • 最后一行输出必须为“所有线程执行完毕”,且该行只在子线程全部打印完成后出现;
  • 由于主线程先于子线程完成自身任务,若去掉 handle.join() 这一行,程序可能在子线程打印完之前就退出,导致输出不完整——这可以反向验证 join() 的等待效果。

满足以上三点,即证明线程创建成功且主线程正确等待了子线程完成。