use std::{panic, sync::Arc, thread};
use super::TaskQueue;
pub struct ThreadPool {
task_queue: Arc<TaskQueue>,
}
impl ThreadPool {
pub fn new(name_pattern: &str, num_threads: usize) -> Self {
let task_queue = Arc::new(TaskQueue::new());
for i in 0..num_threads {
let task_queue = task_queue.clone();
thread::Builder::new()
.name(format!("{name_pattern}-{i}"))
.spawn(move || {
worker_loop(task_queue);
})
.unwrap();
}
ThreadPool { task_queue }
}
pub fn submit<F>(&self, task: F)
where
F: FnOnce() + Send + 'static,
{
self.task_queue.push(Box::new(task));
}
}
fn worker_loop(task_queue: Arc<TaskQueue>) {
loop {
let task = task_queue.pop();
let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| {
task();
}));
}
}