//! Using `select!` to send and receive on the same channel at the same time. //! //! This example is based on the following program in Go. //! //! Source: //! - https://web.archive.org/web/20171209034309/https://www.nada.kth.se/~snilsson/concurrency //! - http://www.nada.kth.se/~snilsson/concurrency/src/matching.go //! //! Copyright & License: //! - Stefan Nilsson //! - Creative Commons Attribution 3.0 Unported License //! - https://creativecommons.org/licenses/by/3.0/ //! //! ```go //! func main() { //! people := []string{"Anna", "Bob", "Cody", "Dave", "Eva"} //! match := make(chan string, 1) // Make room for one unmatched send. //! wg := new(sync.WaitGroup) //! for _, name := range people { //! wg.Add(1) //! go Seek(name, match, wg) //! } //! wg.Wait() //! select { //! case name := <-match: //! fmt.Printf("No one received %s’s message.\n", name) //! default: //! // There was no pending send operation. //! } //! } //! //! // Seek either sends or receives, whichever possible, a name on the match //! // channel and notifies the wait group when done. //! func Seek(name string, match chan string, wg *sync.WaitGroup) { //! select { //! case peer := <-match: //! fmt.Printf("%s received a message from %s.\n", name, peer) //! case match <- name: //! // Wait for someone to receive my message. //! } //! wg.Done() //! } //! ```
use crossbeam_channel::{bounded, select}; use crossbeam_utils::thread;
fn main() { let people = vec!["Anna", "Bob", "Cody", "Dave", "Eva"]; let (s, r) = bounded(1); // Make room for one unmatched send.
// Either send my name into the channel or receive someone else's, whatever happens first. let seek = |name, s, r| {
select! {
recv(r) -> peer => println!("{} received a message from {}.", name, peer.unwrap()),
send(s, name) -> _ => {}, // Wait for someone to receive my message.
}
};
thread::scope(|scope| { for name in people { let (s, r) = (s.clone(), r.clone());
scope.spawn(move |_| seek(name, s, r));
}
})
.unwrap();
// Check if there is a pending send operation. iflet Ok(name) = r.try_recv() {
println!("No one received {}’s message.", name);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.