从通道读取或超时?

Posted

技术标签:

【中文标题】从通道读取或超时?【英文标题】:Read from a channel or timeout? 【发布时间】:2016-10-15 16:25:23 【问题描述】:

对于 Rust 1.9,我想从 mpsc::channel 超时读取。是否有明确的成语来完成这项工作?我已经看到mpsc::Select 中描述的不稳定方法,但this Github discussion 表明它不是一种稳健的方法。是否有更好的推荐方式来实现接收或超时语义?

【问题讨论】:

【参考方案1】:

我不知道你会如何使用标准库通道,但 chan crate 提供了一个 chan_select! 宏:

#[macro_use]
extern crate chan;

use std::time::Duration;

fn main() 
    let (_never_sends, never_receives) = chan::sync::<bool>(1);
    let timeout = chan::after(Duration::from_millis(50));

    chan_select! 
        timeout.recv() => 
            println!("timed out!");
        ,
        never_receives.recv() => 
            println!("Shouldn't have a value!");
        ,
    

【讨论】:

【参考方案2】:

Rust 1.12 引入 Receiver::recv_timeout:

use std::sync::mpsc::channel;
use std::time::Duration;

fn main() 
    let (.., rx) = channel::<bool>();
    let timeout = Duration::new(3, 0);

    println!("start recv");
    let _ = rx.recv_timeout(timeout);
    println!("done!");

【讨论】:

【参考方案3】:

我能够使用标准库获得一些工作。

use std::sync::mpsc::channel;
use std::thread;
use std::time::Duration, Instant;
use std::sync::mpsc::TryRecvError;


fn main() 
    let (send, recv) = channel();

    thread::spawn(move || 
        send.send("Hello world!").unwrap();
        thread::sleep(Duration::from_secs(1)); // block for two seconds
        send.send("Delayed").unwrap();
    );

    println!("", recv.recv().unwrap()); // Received immediately
    println!("Waiting...");

    let mut resolved: bool = false;
    let mut result: Result<&str, TryRecvError> = Ok("Null");

    let now = Instant::now();
    let timeout: u64= 2;

    while !resolved 
        result = recv.try_recv();
        resolved = !result.is_err();
        if now.elapsed().as_secs() as u64 > timeout 
            break;
        
    

    if result.is_ok()
        println!("Results: :?", result.unwrap());
    

    println!("Time elapsed: ", now.elapsed().as_secs());
    println!("Resolved: ", resolved.to_string());

这将旋转 timeout 秒,并导致接收值或错误结果。

【讨论】:

以上是关于从通道读取或超时?的主要内容,如果未能解决你的问题,请参考以下文章

为啥数据被推入通道但从未从接收器 goroutine 中读取?

java.io.IOException: 读取失败,套接字可能关闭或超时,在 Android 5.0.1 Lollipop 版本上读取 ret: -1

java - 如何超时读取Java Socket?

如何使用 Bash 读取超时?

如何使用 Bash 读取超时?

检测到 Sqoop 套接字超时:从大型机读取数据并插入 Hive 时读取超时