Appearance
29.6 Barrier
除了“锁”之外,Rust 标准库还提供了一些其他线程之间的通信方式,比如 Barrier 等。Barrier 是这样的一个类型,它使用一个整数做初始化,可以使得多个线程在某个点上一起等待,然后再继续执行。示例如下:
rust
use std::sync::{Arc, Barrier};
use std::thread;
fn main() {
let barrier = Arc::new(Barrier::new(10));
let mut handlers = vec![];
for _ in 0..10 {
let c = barrier.clone();
// The same messages will be printed together.
// You will NOT see any interleaving.
let t = thread::spawn(move|| {
println!("before wait");
c.wait();
println!("after wait");
});
handlers.push(t);
}
for h in handlers {
h.join().ok();
}
}
这个程序创建了一个多个线程之间共享的 Barrier,它的初始值是 10。我们创建了 10 个子线程,每个子线程都有一个 Arc 指针指向了这个 Barrier,并在子线程中调用了 Barrier::wait 方法。这些子线程执行到 wait 方法的时候,就开始进入等待状态,一直到 wait 方法被调用了 10 次,10 个子线程都进入等待状态,此时 Barrier 就通知这些线程可以继续了。然后它们再开始执行下面的逻辑。
所以最终的执行结果是:先打印出 10 条 before wait,再打印出 10 条 after wait,绝不会错乱。如果我们把 c.wait()这条语句删除掉可以看到,执行结果中,before wait 和 after wait 是混杂在一起的。