[英]Async channel can't stop
I am a beginner in rust asynchronous programming.我是 rust 异步编程的初学者。 I'm writing a program to implement the Sleep Sort algorithm, which can sort a non-negative array.我正在编写一个程序来实现睡眠排序算法,它可以对非负数组进行排序。 The principle of its implementation is that for each element in the array, wait for a period of time before outputting, and the waiting time is proportional to the value of the element.它的实现原理是对数组中的每一个元素,等待一段时间再输出,等待时间与元素的值成正比。 In this way, after a period of time, the array will be output in order from small to large.这样,经过一段时间后,数组就会从小到大依次为output。
use std::time::Duration;
use text_io::read;
use tokio::sync::mpsc::channel;
#[tokio::main]
async fn main() {
let n: u32 = read!();
let (tx, mut rx) = channel::<u32>(n as usize);
let mut before: Vec<u32> = Vec::new();
for _ in 0..n {
let a = read!();
before.push(a);
}
for i in before.into_iter() {
let tx = tx.clone();
tokio::spawn(async move {
tokio::time::sleep(Duration::from_millis((50 * i) as u64)).await;
if let Err(_) = tx.send(i).await {
panic!();
}
});
}
while let Some(i) = rx.recv().await {
println!("{}", i);
}
}
This program prints the correct answer, but it doesn't stop.这个程序打印出正确的答案,但它不会停止。 I don't konw why and how to solve it.我不知道为什么以及如何解决它。
From the recv
documentation (emphasis mine):从recv
文档(强调我的):
This method returns
None
if the channel has been closed and there are no remaining messages in the channel's buffer.如果通道已关闭并且通道缓冲区中没有剩余消息,则此方法返回None
。 [...] The channel is closed when all senders have been dropped, or whenclose
is called. [...]当所有发送者都被删除或调用close
时,通道将关闭。
So, to stop receiving, you need to either drop the extra sender you're still holding in main
before receiving:因此,要停止接收,您需要在接收之前删除仍保留在main
中的额外发件人:
// -- snip --
std::mem::drop(tx);
while let Some(i) = rx.recv().await {
println!("{}", i);
}
or else call rx.close()
.否则调用rx.close()
。 However, this will cause senders trying to send messages afterwards to fail, and thus will break your sleep-sort implementation.但是,这将导致发送者在之后尝试发送消息失败,从而破坏您的睡眠排序实现。 So you need to simply drop the extra sender in this case.因此,在这种情况下,您只需删除额外的发件人即可。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.