简体   繁体   English

异步通道无法停止

[英]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 when close 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM