2015-07-13 3 views
6

Есть ли у ржавчины способ «закрытия» канала, similar to what is available in Go?Закрытие канала, как в Go

Идея состоит в том, чтобы перебирать канал (получать непрерывно), пока канал не покажет, что он не даст никаких значений.

use std::sync::{Arc, Mutex}; 
use std::thread; 
use std::sync::mpsc; 

fn main() { 
    let data = Arc::new(Mutex::new(0u32)); 
    let (tx, rx) = mpsc::channel::<u32>(); 
    { 
     let (data, tx) = (data.clone(), tx.clone()); 
     thread::spawn(move || { 
      for _ in 0..10 { 
       let mut data = data.lock().unwrap(); 
       *data += 1; 
       tx.send(*data).unwrap(); 
      } 
      // *** How could I close the channel here, to signal the work is done? 
     }); 
    } 

    // *** How can I detect a closed channel here? Pattern matching? 
    for _ in 0..10 { 
     let x = rx.recv().unwrap(); 
     println!("{}", x); 
    } 
} 
+1

У вас есть код, который представляет собой то, что вы пытаетесь сделать? – tadman

+0

@tadman [довольно глупо] Пример добавлен – jocull

+1

Документы уже ответили на это сообщение: https://doc.rust-lang.org/nightly/std/sync/mpsc/struct.Sender.html#method.send Удаление команды ' tx' (как это происходит после цикла for после окончания области) приведет к тому, что 'rx' вернет' Err' вместо 'Ok' на следующий' recv'. Затем вы можете сопоставить соответствие по результату 'recv' для проверки' Ok' или 'Err'. –

ответ

13

Канал закрыт, когда все отправители упали. В вашем коде вы клонируете и даете по одному в каждом потоке, они падают, как они должны, когда заканчиваются нити. Последний отправитель находится в основном потоке, и вы должны отбросить его, как только будут созданы все потоки: drop(tx).

Наконец, самый простой способ получить это, послеdrop(tx).

for elt in rx { 
    /* */ 
} 

Этот цикл заканчивается, когда канал закрыт.

+0

То, что мне нужно! Вот упрощенный рабочий пример на игровой площадке: http://is.gd/jfSQD2 – jocull

+1

Вот пример простой функции генератора. http://is.gd/DQb0Ot – jocull

+0

Это круто, но невероятно расточительный путь к итерации (это тоже поток ОС), поэтому я не видел этого в Rust. – bluss

Смежные вопросы