Appearance
27.2 启动线程
Rust 标准库中与线程相关的内容在 std::thread 模块中。Rust 中的线程是对操作系统线程的直接封装。
创建线程的方法为:
rust
use std::thread;
thread::spawn(move || {
// 这里是新建线程的执行逻辑
});
默认情况下,新创建的子线程与原来的父线程是分离的关系。也就是说,子线程可以在父线程结束后继续存在,除非父线程是主线程。因为我们知道,如果一个进程的主线程也退出了,这个进程就会终止,其他所有的线程也会随之结束。
如果我们需要等待子线程执行结束,那么可以使用 join 方法:
rust
use std::thread;
// child 的类型是 JoinHandle<T>,这个 T 是闭包的返回类型
let child = thread::spawn(move || {
// 子线程的逻辑
});
// 父线程等待子线程结束
let res = child.join();
如果我们需要为子线程指定更多的参数信息,那么在创建的时候可以使用 Builder 模式:
rust
use std::thread;
thread::Builder::new().name("child1".to_string()).spawn(move || {
println!("Hello, world!");
});
thread 模块还提供了下面几个工具函数。
(1)thread::sleep(dur:Duration)
使得当前线程等待一段时间继续执行。在等待的时间内,线程调度器会调度其他的线程来执行。
(2)thread::yield_now()
放弃当前线程的执行,要求线程调度器执行线程切换。
(3)thread::current()
获得当前的线程。
(4)thread::park()
暂停当前线程,进入等待状态。当 thread::Thread::unpark(&self)方法被调用的时候,这个线程可以被恢复执行。
(5)thread::Thread::unpark(&self)
恢复一个线程的执行。
以上函数的综合使用见如下示例:
rust
use std::thread;
use std::time::Duration;
fn main() {
let t = thread::Builder::new()
.name("child1".to_string())
.spawn(move || {
println!("enter child thread.");
thread::park();
println!("resume child thread");
}).unwrap();
println!("spawn a thread");
thread::sleep(Duration::new(5,0));
t.thread().unpark();
t.join();
println!("child thread finished");
}