练习一:频道,信息传递
上游:work_send, work_recv
下游:main_sand, main_recv
下游的main_recv依靠while let Ok(msg) = main_recv.recv() {...}保持接收(尽管这个语法和if let 一样有些奇怪,但是channel中的recv处理信号的常见写法),当上游work_recv接收到Quit信息后通过main_send发布WorkQuit信息
use crossbeam_channel::unbounded;
use std::thread;
use std::thread::JoinHandle;
enum WorkerMsg {
PrintData(String),
Sum(i64, i64),
Quit,
}
enum MainMsg {
SumResult(i64),
WorkerQuit,
}
fn main() {
let (worker_send, worker_recv) = unbounded();
let (main_send, main_recv) = unbounded();
let worker = thread::spawn(move || loop{
match worker_recv.recv() {
Ok(msg) => match msg {
WorkerMsg::PrintData(d) => println!("Worker:{d}"),
WorkerMsg::Sum(a, b) => {
main_send.send(MainMsg::SumResult(a + b));
},
Quit => {
println!("Worker Quit");
main_send.send(MainMsg::WorkerQuit);
break;
},
},
Err(e) => {
println!("Worker:discount");
main_send.try_send(MainMsg::WorkerQuit);
break;
}
}
});
worker_send.send(WorkerMsg::PrintData("woker thread start".to_string()));
worker_send.send(WorkerMsg::Sum(10, 5));
worker_send.send(WorkerMsg::Quit);
while let Ok(msg) = main_recv.recv() {
match msg {
MainMsg::SumResult(ans) => println!("answer is :{ans}"),
MainMsg::WorkerQuit => {
println!("Main: worker is terminated");
break;
},
}
worker.join();
}
练习二:多重匹配,接收者(reciver)对象
在spawn_light_thread函数中接受一个接收者对象产生线程(JoinHandle<LightStatus>),线程数据来源于接收者的频道信息,函数中第一层是显式的初始化一个线程,之后light_status是信息,接着任然通过while let匹配信息直到Discount结束循环。
use crossbeam_channel::{unbounded, Receiver, Sender};
use std::thread::{self, JoinHandle};
enum LightMsg {
ChangeColor(u8, u8, u8),
Discountect,
On,
Off,
}
enum LightStatus {
Off,
On,
}
fn spawn_light_thread(recv: Receiver<LightMsg>) ->JoinHandle<LightStatus> {
let res:JoinHandle<LightStatus> = thread::spawn(move || {
let mut light_status = LightStatus::Off;
while let Ok(msg) = recv.recv() {
match msg {
LightMsg::ChangeColor(r, g, b) => {
println!("Color change to:{r}{g}{b}");
match light_status {
LightStatus::On =>println!("Light is On"),
LightStatus::Off =>println!("Light is Off"),
}
},
LightMsg::On => {
println!("turn Light On");
light_status = LightStatus::On;
},
LightMsg::Off => {
println!("turn Light Off");
light_status = LightStatus::Off;
},
LightMsg::Discountect => {
println!("Discountect");
light_status = LightStatus::Off;
break;
},
}
}
light_status
});
res
}
fn main() {
let(send, recv) = unbounded();
let light = spawn_light_thread(recv);
send.send(LightMsg::On);
send.send(LightMsg::ChangeColor(12, 45, 35));
send.send(LightMsg::Off);
send.send(LightMsg::ChangeColor(6, 76, 105));
send.send(LightMsg::Discountect);
let light_status = light.join();
}
实际上channel是一种封装好的函数回调方法。