练习一
use std::sync::Mutex;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
struct DigitalSignBoard {
display: Arc<Mutex<String>>,
}
impl DigitalSignBoard {
fn update(&self) {
let data = self.display.lock().unwrap();
println!("sign data :{data}");
}//data.display unlock
}
fn spawn_display_thread(display_data: Arc<Mutex<String>>) {
thread::spawn(|| {
let board = DigitalSignBoard {
display: display_data,
};
loop {
board.update();
thread::sleep(Duration::from_millis(200));
}
});
}
fn change_data(display_data: Arc<Mutex<String>>, new_data: &str) {
let mut data = display_data.lock().unwrap();
*data = new_data.to_string();
}
fn main() {
let dispaly_data = Arc::new(Mutex::new("inital".to_string()));
spawn_display_thread(Arc::clone(&dispaly_data));
thread::sleep(Duration::from_millis(200));
change_data(Arc::clone(&dispaly_data),"test massage");
thread::sleep(Duration::from_millis(200));
change_data(Arc::clone(&dispaly_data),"RUST is so hard to learn");
thread::sleep(Duration::from_millis(200));
}
练习二
use crossbeam_channel::{unbounded, Receiver, Sender};
use std::collections::vec_deque::VecDeque;
use std::thread::{self, JoinHandle};
use std::time::Duration;
use std::sync::{Mutex, Arc};
#[derive(Clone)]
enum Job {
Print(String),
Sum(isize, isize),
}
#[derive(Clone)]
enum Message {
AddJob(Job),
Quit,
}
struct Worker<M> {
send: Sender<M>,
recv: Receiver<M>,
handle: JoinHandle<()>,
}
impl Worker<Message> {
fn add_job(&self, job: Job) {
self.send.send(Message::AddJob(job)).expect("failed to send");
}
fn join(self, job: Job) { // move can not be refrence
self.handle.join().expect("failed to join the thread");
}
fn send_msg(&self, msg: Message) {
self.send.send(msg).expect("failed to send");
}
}
fn spawn_worker(count: Arc<Mutex<usize>>) -> Worker<Message> {
let (send, recv) = unbounded();
let recv_thread:Receiver<_> = recv.clone();// clone the Receiver<_>
let handle:JoinHandle<_> = thread::spawn(move|| {
let mut jobs = VecDeque::new();
loop {
loop{
for job in jobs.pop_front() {
match job {
Job::Print(msg) => println!("{msg}"),
Job::Sum(l, r) => println!("{}", l + r),
}
let mut count = count.lock().unwrap(); // MutexGuard<_>
*count += 1;
}
if let Ok(msg) = recv_thread.try_recv() {
match msg {
Message::AddJob(job) => {
jobs.push_back(job);
continue;
},
Message::Quit => return,
}
} else {
break;
}
}
thread::sleep(Duration::from_millis(100));
}
});
Worker {
send,
recv,
handle,
}
}
fn main() {
let jobs = vec![
Job::Print("helllo".to_string()),
Job::Sum(34,56),
Job::Print("world".to_string()),
Job::Sum(1,0),
Job::Print("c'est".to_string()),
Job::Sum(12,627),
Job::Print("bone".to_string()),
];
let jobs_sent = jobs.len();
let job_counter = Arc::new(Mutex::new(0));
let mut workers = vec![];
for _ in 0..4 {
let worker = spawn_worker(Arc::clone(&job_counter));
workers.push(worker);
}
let mut worker_ring = workers.iter().cycle();
for job in jobs.into_iter() {
let worker = worker_ring.next().expect("failed to get worker");
worker.add_job(job);
}
}