2015-09-08 12 views
5

Sto utilizzando la ruggine websocket library di parlare con le cose e ho questa discussione che sembra più o meno in questo modo:Lettura due iteratori bloccanti

thread::spawn(move || { 
    while let Ok(Message::Text(text)) = receiver.recv_message() { 
     /* Do some stuff */ 
    } 
}); 

Il ricevitore di cui sopra può anche essere un iteratore blocco:

thread::spawn(move || { 
    for message in receiver.incoming_messages() { 
     /* Do same stuff */ 
    } 
}); 

Voglio inviare un segnale a questo thread dicendogli di smettere di fare le cose. Ho pensato che un mpsc::channel sarebbe ottimo per questo invio di segnali. select! sembrava la strada da percorrere, ma funziona solo se tutti i canali sono tipi mpsc::channel.

C'è qualcosa che può unire due iteratori di blocco e fornire l'output mentre i dati arrivano? O qualsiasi altra soluzione a questo problema? Mi piacerebbe evitare di creare un thread per ciascuna fonte di input e gestire la mia coda.

+0

Busy attesa ... (vale a dire, un ciclo su tutti i canali di picco per vedere se hanno qualche cosa, e la resa/sonno alla fine del ciclo, se non hai niente) –

+0

@MatthieuM. Come si può dare un'occhiata a un iteratore di blocco? Forse mi manca qualcosa, ma poiché sta bloccando, il controllo non verrà restituito finché non sarà disponibile un elemento dall'iteratore controllato. Dovresti creare un thread per blocco iteratore, come suggerito da OP. – Shepmaster

+1

@Shepmaster: Dannato; lieto che fosse solo un commento: p Anche se ho solo suggerito scherzando comunque perché è più un hack che una vera soluzione: x –

risposta

1

C'è qualcosa che può unire due iteratori di blocco e fornire l'output mentre i dati arrivano? O qualsiasi altra soluzione a questo problema?

Anche se spero che qualcuno mi smentisca, penso che la risposta debba essere "no". Per definizione, qualcosa che blocca impedirà l'esecuzione di ulteriori lavori su quel thread. Avresti bisogno di qualcosa che possa distinguere tra gli stati di "fatto", "niente da leggere" e "qualcosa da leggere" e che non può essere costruito in cima a blocchi che danno solo due di questi stati.

Vorrei evitare di creare un thread per ciascuna fonte di input e gestire la mia coda.

Non vedo alcun modo per aggirare questo. Poiché un iteratore di blocco blocca il thread, la presenza di più thread consente di aggiungere lo stato di "nothing to read".

La soluzione migliore implicherebbe che entrambe le sorgenti di input abbiano tutti e 3 gli stati.

loop { 
    if let Ok(Message::Text(text)) = receiver.recv_message() { 
     // Do some stuff 
    } else if let Err(TryRecvError::Disconnected) = kill.try_recv() { 
     break; 
    } else { 
     // Something intelligent for the other cases? 
    } 
} 
+0

Vorrei che ci fosse anche un modo migliore. : / –

Problemi correlati