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

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

【问题讨论】:

    标签: multithreading rust channels


    【解决方案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 秒,并导致接收值或错误结果。

        【讨论】:

          猜你喜欢
          • 2018-10-04
          • 1970-01-01
          • 2012-11-25
          • 2022-11-17
          • 2010-12-23
          • 2020-06-21
          • 2019-08-14
          • 1970-01-01
          • 2016-11-14
          相关资源
          最近更新 更多