2015-09-08 12 views
5

Ich verwende den Rust websocket library, um die Dinge zu sprechen, und ich habe diesen Thread, der in etwa wie folgt aussieht:Lese zwei Sperr Iteratoren

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

Der obige Empfänger kann auch ein Sperr Iterator sein:

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

Ich möchte ein Signal an diesen Thread senden, er soll aufhören, Dinge zu tun. Ich dachte, ein mpsc::channel wäre großartig für dieses Signal-Senden. select! schien wie der Weg zu gehen, aber es funktioniert nur, wenn alle Kanäle mpsc::channel Typen sind.

Gibt es etwas, das zwei blockierende Iteratoren beitreten kann und Ausgabe als Daten zur Verfügung stellt? Oder irgendeine andere Lösung für dieses Problem? Ich möchte vermeiden, einen Thread für jede Quelle der Eingabe zu erstellen und meine eigene Warteschlange zu verwalten.

+0

Busy Waiting ... (dh Schleife über alle Kanäle Peaking, um zu sehen, ob sie etwas haben, und Ertrag/Schlaf am Ende der Iteration, wenn Sie nichts bekommen) –

+0

@MatthieuM. Wie kann man einen blockierenden Iterator sehen? Vielleicht verpasse ich etwas, aber weil es blockiert, wird die Kontrolle nicht zurückgegeben, bis ein Element verfügbar ist, das vom Iterator geprüft wird. Sie müssten einen Thread pro blockierenden Iterator erstellen, wie OP vorgeschlagen hat. – Shepmaster

+1

@Shempmaster: Verdammt; Ich bin froh, dass es nur ein Kommentar war: p Obwohl ich nur im Scherz vorgeschlagen habe, weil es eher ein Hack als eine echte Lösung ist: x –

Antwort

1

Gibt es etwas, das zwei blockierende Iteratoren beitreten kann und Ausgabe liefert, wenn Daten reinkommen? Oder irgendeine andere Lösung für dieses Problem?

Obwohl ich sicherlich hoffe jemand beweist mich falsch, ich denke, die Antwort muss "Nein" sein. Per Definition blockiert etwas, das blockiert, dass weitere Arbeiten an diesem Thread ausgeführt werden. Sie würden etwas brauchen, das zwischen den Zuständen "fertig", "nichts zu lesen" und "etwas zu lesen" unterscheiden kann und das nicht auf Bausteinen aufgebaut werden kann, die nur zwei dieser Zustände ergeben.

Ich möchte vermeiden, einen Thread für jede Eingabequelle zu erstellen und meine eigene Warteschlange zu verwalten.

Ich sehe keinen Weg um diese. Da ein blockierender Iterator den Thread blockiert, können Sie mit mehreren Threads den Status "Nichts zum Lesen" hinzufügen.

Die bessere Lösung würde bedeuten, dass beide Eingangsquellen alle 3 Zustände haben.

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

Ich wünschte, es gäbe einen besseren Weg. : / –