多线程

使用thread::spawn创建线程:

use std::thread;
use std::time::Duration;
 
fn main() {
    let handle = thread::spawn(|| {
        for i in 1..10 {
            println!("hi number {} from the spawned thread", i);
            thread::sleep(Duration::from_millis(1));
        }
    });
 
    handle.join().unwrap();
 
    for i in 1..5 {
        println!("hi number {} from the main thread", i);
        thread::sleep(Duration::from_millis(1));
    }
}
  • 线程内部的代码使用闭包来执行
  • main一旦结束,程序就立即结束。因此在其它子线程完成任务前,需要保持main线程的存活
  • 使用join()方法可以阻塞当前线程,直至子线程执行结束。

在多线程中使用环境变量

use std::thread;
 
fn main() {
    let v = vec![1, 2, 3];
    let handle = thread::spawn(move || {
        println!("Here's a vector: {:?}", v);
    }); 
    handle.join().unwrap();
}

线程屏障(Barrier)

Barries可以让多个线程都执行都某个点后,再继续一起往后执行:

use std::sync::{Arc, Barrier};
use std::thread;
 
fn main() {
    let mut handles = Vec::with_capacity(3);
    let barrier = Arc::new(Barrier::new(3));
 
    for _ in 0::3 {
         let b = barries.clone();
         handles.push(thread::spawn(move || {
             println!("before wait");
             b.wait();
             pritnln!("after wait");
         }));
    }
 
    // 防止main函数执行完毕,子线程中断执行
    for handle in handles {
        handle.join().unwrap();
    }
}

打印结果

before wait
before wait
before wait
after wait
after wait
after wait

线程局部变量(Thread Local Variable)

使用thread_local宏可以初始化线程局部变量,然后在线程内部使用该变量的with方式获取变量值。

use std::cell::RefCell;
use std::thread;
 
thread_local!(static FOO: RefCell<u32> = RefCell::new(1));
 
FOO.with(|f| {
    assert_eq!(*f.borrow(), 1);
    *f.borrow_mut() = 2;    
});
 
let t = thread::spawn(move || {
    // 独立的FOO值
    FOO.with(|f| {
         assert_eq!(*f.borrow(), 1);
         *f.borrow_mut() = 3;
    });
});
 
t.join().unwrap();
FOO.with(|f| {
    // 主线程的值仍然是2
    assert_eq!(*f.borrow(), 2)
});

条件控制

use std::thread;
use std::sync::{Arc, Mutex, Condvar};
 
fn main() {
    let pair = Arc::new((Mutex::new(false), Condvar::new()));
    let pair2 = pair.clone();
 
    thread::spawn(move || {
        let (lock, cvar) = &*pair2;
        let mut started = locl.lock().unwrap();
        println!("changing started");
        *started = true;
        cvar.notify_one();
    });
 
    let (lock, cvar) = &*pair;
    let mut started = locl.lock().unwrap();
    while !*started {
        started = cvar.wait(started).unwrap();
    }
    println!("started changed");
}
  1. main线程首先进入while循环,调用wait方法挂起等待子线程的通知,并释放了锁started
  2. 子线程获取到锁,并将其修改为true,然后调用条件变量的notify_one方法来通知主线程继续执行