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() 会确保主线程等待子线程完成剩余的工作。
线程执行时序
编译与运行
确保已安装 Rust 工具链(包含 cargo)。在项目目录下创建 src/main.rs 并粘贴上述代码,然后在终端执行:
cargo run
验证方法与判定标准
运行程序后,观察终端输出。判定标准如下:
- 输出中应包含“主线程打印: 1”至“主线程打印: 3”以及“子线程打印: 1”至“子线程打印: 5”的全部内容;
- 最后一行输出必须为“所有线程执行完毕”,且该行只在子线程全部打印完成后出现;
- 由于主线程先于子线程完成自身任务,若去掉
handle.join()这一行,程序可能在子线程打印完之前就退出,导致输出不完整——这可以反向验证join()的等待效果。
满足以上三点,即证明线程创建成功且主线程正确等待了子线程完成。