use std::sync::{Arc, mpsc, Mutex};
use std::thread;
use std::thread::JoinHandle;
use json::{JsonValue};
type Job = Box<dyn FnOnce(usize) -> JsonValue + 'static + Send>;
enum Message {
End,
NewJob(Job),
}
struct Worker {
_id: usize,
t: Option<JoinHandle<Vec<JsonValue>>>,
}
impl Worker {
fn new(id: usize, receiver: Arc::<Mutex<mpsc::Receiver<Message>>>) -> Worker {
let t = thread::spawn(move || {
let mut list = vec![];
loop {
let message = receiver.lock().unwrap().recv().unwrap();
match message {
Message::NewJob(job) => {
list.push(job(id));
}
Message::End => {
break;
}
}
}
list
});
Worker {
_id: id,
t: Some(t),
}
}
}
pub struct Pool {
workers: Vec<Worker>,
max_workers: usize,
sender: mpsc::Sender<Message>,
}
impl Pool {
pub fn new(max_workers: usize) -> Pool {
if max_workers <= 0 {
panic!("max_workers 必须大于0")
}
let (tx, rx) = mpsc::channel();
let mut workers = Vec::with_capacity(max_workers);
let receiver = Arc::new(Mutex::new(rx));
for i in 0..max_workers {
workers.push(Worker::new(i, Arc::clone(&receiver)));
}
Pool { workers, max_workers, sender: tx }
}
pub fn execute<F>(&self, f: F) where F: 'static + Send + FnOnce(usize) -> JsonValue {
let job = Message::NewJob(Box::new(f));
self.sender.send(job).unwrap();
}
pub fn end(&mut self) -> JsonValue {
for _ in 0..self.max_workers {
self.sender.send(Message::End).unwrap();
}
let mut list = vec![];
for w in self.workers.iter_mut() {
if let Some(t) = w.t.take() {
let data = t.join().unwrap();
list.extend(data);
}
}
return JsonValue::from(list);
}
pub fn insert_all(&mut self) -> (Vec<String>, String) {
for _ in 0..self.max_workers {
self.sender.send(Message::End).unwrap();
}
let mut list = String::new();
let mut id = vec![];
for w in self.workers.iter_mut() {
if let Some(t) = w.t.take() {
let data = t.join().unwrap();
for item in data.iter() {
id.push(item[0].to_string());
list = format!("{},{}", list, item[1].clone());
}
}
}
return (id, list);
}
}