2022-09-07 05:11:09 +00:00
|
|
|
// ./src/std_misc/channels.md
|
|
|
|
|
|
|
|
use std::sync::mpsc::{Sender, Receiver};
|
|
|
|
use std::sync::mpsc;
|
|
|
|
use std::thread;
|
|
|
|
|
|
|
|
static NTHREADS: i32 = 3;
|
|
|
|
|
|
|
|
fn part0() {
|
|
|
|
// Channels have two endpoints: the `Sender<T>` and the `Receiver<T>`,
|
|
|
|
// where `T` is the type of the message to be transferred
|
|
|
|
// (type annotation is superfluous)
|
|
|
|
let (tx, rx): (Sender<i32>, Receiver<i32>) = mpsc::channel();
|
|
|
|
let mut children = Vec::new();
|
|
|
|
|
|
|
|
for id in 0..NTHREADS {
|
|
|
|
// The sender endpoint can be copied
|
|
|
|
let thread_tx = tx.clone();
|
|
|
|
|
|
|
|
// Each thread will send its id via the channel
|
|
|
|
let child = thread::spawn(move || {
|
|
|
|
// The thread takes ownership over `thread_tx`
|
|
|
|
// Each thread queues a message in the channel
|
|
|
|
thread_tx.send(id).unwrap();
|
|
|
|
|
|
|
|
// Sending is a non-blocking operation, the thread will continue
|
|
|
|
// immediately after sending its message
|
|
|
|
println!("thread {} finished", id);
|
|
|
|
});
|
|
|
|
|
|
|
|
children.push(child);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Here, all the messages are collected
|
|
|
|
let mut ids = Vec::with_capacity(NTHREADS as usize);
|
|
|
|
for _ in 0..NTHREADS {
|
|
|
|
// The `recv` method picks a message from the channel
|
|
|
|
// `recv` will block the current thread if there are no messages available
|
|
|
|
ids.push(rx.recv());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for the threads to complete any remaining work
|
|
|
|
for child in children {
|
|
|
|
child.join().expect("oops! the child thread panicked");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Show the order in which the messages were sent
|
|
|
|
println!("{:?}", ids);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn main() {
|
2022-09-08 04:19:12 +00:00
|
|
|
part0();
|
2022-09-07 05:11:09 +00:00
|
|
|
}
|
|
|
|
|