我是异步编程的新手,因此很难理解不同的方法在行为上的差异。
考虑一下时雄在github repo(www.example.com)上给出的例子chat.rs:
// snip
loop {
tokio::select! {
// A message was received from a peer. Send it to the current user.
Some(msg) = peer.rx.recv() => {
// do something
}
result = peer.lines.next() => match result {
// A message was received from the current user, we should
// broadcast this message to the other users.
Some(Ok(msg)) => {
// do something
}
Some(Err(e)) => {
// handle error
}
// The stream has been exhausted.
None => break,
},
}
}
// do something
在两个时雄::spawn上使用循环select!的好处是什么,如下所示:
let handle_1 = tokio::spawn(async move {
while let Some(msg) = peer.rx.recv() {
// do something
}
});
let handle_2 = tokio::spawn (async move {
loop {
let result = peer.lines.next();
match result {
Some(Ok(msg)) => {
// do something
},
Some(Err(e)) => {
// handle error
},
None => break,
};
}
});
handle_1.await;
handle_2.await;
// do something
1条答案
按热度按时间c2e8gylq1#
总的来说,
select!
更高效,因为它不需要产生新任务,这非常便宜,但仍然比轮询future昂贵。1.如果频繁出现消息,使任务更受CPU限制,则建议派生一个新任务,因为
select!
在同一线程上运行所有future,而spawn()
可能在多线程运行时使用不同的线程。select!
中的future应该是 cancellation-safe,这意味着删除未完成的future是安全的,并且不会导致任何数据丢失。如果不是这样,可能会有bug。这使得用select!
编程比用任务编程更困难。例如,请参见this post。