Basics of Rust Concurrency「1」

1,412 阅读2分钟

Threads in Rust

程序开始运行时,存在一个确定且唯一的 thread: main thread。该 thread 将会执行你当前程序的主函数,并且可能会在未来产生更多的其他 thread

在Rust中,可以通过调用标准库的 thread::spawn 生成新的 thread 。此函数需要传入一个参数:新 thread 要执行的函数。一旦传入的函数执行完毕,则当前 thread 停止

先来看个例子:

use std::thread;

fn main() {
    thread::spawn(f);
    thread::spawn(f);

    println!("Hello from the main thread.");
}

fn f() {
    println!("Hello from another thread!");

    let id = thread::current().id();
    println!("This is my thread id: {id:?}");
}
  1. main thread 中连续调用两次 thread::spawn → 生成两个子thread

  2. 每个子thread,传入相同的 f()

    1. 打印msg
    2. 显示当前 threadthread id
📢 THREAD ID
  1. Rust标准库为每个线程分配了一个唯一的标识符。这个标识符可以通过 Thread::id() 获取到,其类型为 ThreadId
  2. 除了复制它并检查是否相等之外,你对 ThreadId 能做的并不多。
  3. 不能保证这些ID是连续分配的;只能保证每个线程的ID都是不同的。

不过你多次运行上述代码你会发现,每次的输出可能是不同的。下面是在我这台机器的输出:

Hello from the main thread.
Hello from another thread!
This is my thread id:

奇怪的是:部分输出失效了(ThreadId)。

原因是主线程在产生新的线程后,还没来得及执行新线程中的函数,main函数就结束执行。而main返回就意味着程序退出,即使还有其他子线程在运行。

如果想要确保子线程在主线程返回之前执行完毕,我们可以加入一些 等待 。这里可以使用 spawn() 返回的 JoinHandle

fn main() {
    let t1 = thread::spawn(f);
    let t2 = thread::spawn(f);

    println!("Hello from the main thread.");

    t1.join().unwrap();
    t2.join().unwrap();
}

thread.join() 会等待此线程(调用该方法的线程)执行完毕,并返回一个 thread::Result 。如果该线程因为 panic 而没有成功完成功能,Result 中将包含恐慌信息。

Hello from the main thread.
Hello from another thread!
This is my thread id: ThreadId(3)
Hello from another thread!
This is my thread id: ThreadId(2)

运行多次,改变的是msg的打印顺序。

Hello from the main thread.
Hello from another thread!
Hello from another thread!
This is my thread id: ThreadId(2)
This is my thread id: ThreadId(3)

TODO!!!

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情