Channel
Goのチャネルのようにメッセージパッシングによるデータのやり取りをするもの
multi-producer, single-consumer
std::sync::mpsc
single-producer, single-consumer
tokioの tokio::sync::oneshot multi-producer, multi-consumer
tokioの tokio::sync::broadcast, tokio::sync::watch 同期か非同期か
bounded
バッファサイズが指定できて、バッファがいっぱいの場合は送信がブロッキングされる
unbounded
バッファサイズが無限で、ブロッキングしない
複数のスレッドからチャネルを利用する
2つ以上のスレッドにわたす場合はcloneしてあげる必要がある code:_.rs
// Create a shared channel that can be sent along from many threads.
let (tx, rx) = mpsc::channel();
for i in 0..10 {
let tx = tx.clone(); // クローンする
thread::spawn(move || {
tx.send(i).unwrap();
println!("sent>{}", i);
io::stdout().flush().unwrap();
});
}
複数のスレッドにChannelを受け渡すにはCloneが必要だが、逆に同じスレッド内であれば、参照を使い回せるので関数の引数に入れるときは参照で受け取るのもアリ It’s also possible to share senders and receivers by reference:
code:_.rs
use tokio::sync::broadcast;
async fn main() {
let (tx, mut rx) = broadcast::channel(10);
let handle = tokio::spawn(async move {
recv_ref(&mut rx).await;
});
for _ in 0..5 {
send_ref(&tx);
}
drop(tx);
handle.await.unwrap();
}
async fn recv_ref(ch: &mut broadcast::Receiver<String>) {
loop {
match ch.recv().await {
Ok(msg) => {
println!("recv: {:?}", msg);
}
Err(err) => {
println!("recv error: {:?}", err);
return;
}
}
}
}
fn send_ref(ch: &broadcast::Sender<String>) {
ch.send("hello".to_string()).unwrap();
}