std::sync::mpsc
,为何crossbeam又要搞出一套channel呢?首先咱们来看看标准库中的channel有哪些不足吧
标准库中channel的不足
-
Receiver不能被clone,是MPSC的channel。理想情况咱们但愿能有MPMC的channel -
Sender和Receiver不是 Sync
。 -
在Go语言中,channel通常和 select
语句一块儿使用,可是标准库中的channel并不支持select -
有限容量(Bounded)的channel内部实现就是一个简单的 Mutex<VecDeque<T>>
,性能比Go语言的channel还差 -
有Sender(=Unbouded)和SyncSender(=Bounded)的区分,用起来不统一。
crossbeam中增强版的channel
Mutex<VecDeque<T>>
产生的瓶颈么,这里也相似。对于1-3点:(在此以前咱们先简单讲下如何建立crossbeam的channel)
建立channel
use crossbeam_channel::bounded;
// 建立一个容量是5的channel
let (s, r) = bounded(5);
// 5条消息以内都不会阻塞
for i in 0..5 {
s.send(i).unwrap();
}
// 超过5条就会阻塞了
// s.send(5).unwrap();
use crossbeam_channel::unbounded;
// 建立一个无限容量的channel
let (s, r) = unbounded();
// 不会阻塞
for i in 0..1000 {
s.send(i).unwrap();
}
1 支持MPMC
use std::thread;
use crossbeam_channel::bounded;
let (s1, r1) = bounded(0);
let (s2, r2) = (s1.clone(), r1.clone());
// 起一个线程先接受一个消息而后发出一个消息
thread::spawn(move || {
r2.recv().unwrap();
s2.send(2).unwrap();
});
// 发送一个消息而后接受一个消息
s1.send(1).unwrap();
r1.recv().unwrap();
2 Sender和Receiver是Sync
use std::thread;
use crossbeam_channel::bounded;
use crossbeam_utils::thread::scope;
let (s, r) = bounded(0);
scope(|scope| {
// 起一个线程先接受一个消息而后发出一个消息
scope.spawn(|_| {
r.recv().unwrap();
s.send(2).unwrap();
});
// 发送一个消息而后接受一个消息
s.send(1).unwrap();
r.recv().unwrap();
}).unwrap();
3 支持select
select
宏,支持使用
default
分支处理超时等逻辑
use std::thread;
use std::time::Duration;
use crossbeam_channel::unbounded;
let (s1, r1) = unbounded();
let (s2, r2) = unbounded();
thread::spawn(move || s1.send(10).unwrap());
thread::spawn(move || s2.send(20).unwrap());
select! {
recv(r1) -> msg => assert_eq!(msg, Ok(10)),
recv(r2) -> msg => assert_eq!(msg, Ok(20)),
default(Duration::from_secs(1)) => println!("timed out"),
}
小结
本文分享自微信公众号 - Rust语言中文社区(rust-china)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。微信