Skip to content

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");
}

Released under the MIT License