cratosw

线程

线程

Rust 标准库支持线程、同步与并发。
语言和标准库本身提供基础能力,更多高级并发能力由生态 crate 提供, 本文不展开。

下表给出 .NET 与 Rust 在线程相关类型/方法上的近似映射:

.NETRust
Threadstd::thread::thread
Thread.Startstd::thread::spawn
Thread.Joinstd::thread::JoinHandle
Thread.Sleepstd::thread::sleep
ThreadPool-
Mutexstd::sync::Mutex
Semaphore-
Monitorstd::sync::Mutex
ReaderWriterLockstd::sync::RwLock
AutoResetEventstd::sync::Condvar
ManualResetEventstd::sync::Condvar
Barrierstd::sync::Barrier
CountdownEventstd::sync::Barrier
Interlockedstd::sync::atomic
Volatilestd::sync::atomic
ThreadLocalstd::thread_local

在 C#/.NET 中,创建线程并等待结束的写法如下:

using System;
using System.Threading;

var thread = new Thread(() => Console.WriteLine("Hello from a thread!"));
thread.Start();
thread.Join(); // wait for thread to finish

Rust 等价写法:

use std::thread;

fn main() {
    let thread = thread::spawn(|| println!("Hello from a thread!"));
    thread.join().unwrap(); // wait for thread to finish
}

在 .NET 中,“创建线程对象”与“启动线程”是两个动作;Rust 里 thread::spawn 会同时完成创建与启动。

.NET 线程支持通过参数传值:

#nullable enable

using System;
using System.Text;
using System.Threading;

var t = new Thread(obj =>
{
    var data = (StringBuilder)obj!;
    data.Append(" World!");
});

var data = new StringBuilder("Hello");
t.Start(data);
t.Join();

Console.WriteLine($"Phrase: {data}");

更现代/简洁的 C# 常用闭包:

using System;
using System.Text;
using System.Threading;

var data = new StringBuilder("Hello");

var t = new Thread(obj => data.Append(" World!"));

t.Start();
t.Join();

Console.WriteLine($"Phrase: {data}");

Rust 没有“线程启动时直接传参”的 thread::spawn 变体,通常通过闭包捕获数据:

use std::thread;

fn main() {
    let data = String::from("Hello");
    let handle = thread::spawn(move || {
        let mut data = data;
        data.push_str(" World!");
        data
    });
    println!("Phrase: {}", handle.join().unwrap());
}

要点:

  • 这里必须使用 move,把 data 的所有权移动到线程闭包中。移动后,main 里的原变量不能再直接使用;如需复用,需要复制或克隆。
  • Rust 线程与 C# Task 类似,也可以返回值,join 可拿到该返回值。
  • C# 也能用闭包传数据,但通常不需要显式处理所有权;对象生命周期由 GC 管理。

On this page