You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

lib.rs 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. use std::thread;
  2. use std::sync::{mpsc, Mutex, Arc};
  3. enum Message {
  4. NewJob(Job),
  5. Terminate
  6. }
  7. pub struct ThreadPool{
  8. workers: Vec<Worker>,
  9. sender: mpsc::Sender<Message>,
  10. }
  11. type Job = Box<dyn FnOnce() + Send + 'static>;
  12. impl ThreadPool {
  13. pub fn new(size: usize) -> ThreadPool {
  14. assert!(size > 0);
  15. let (sender, receiver) = mpsc::channel();
  16. let receiver = Arc::new(Mutex::new(receiver));
  17. let mut workers = Vec::with_capacity(size);
  18. for id in 0..size {
  19. workers.push(Worker::new(id, Arc::clone(&receiver)));
  20. }
  21. ThreadPool {
  22. workers,
  23. sender,
  24. }
  25. }
  26. pub fn execute<F>(&self, f: F)
  27. where
  28. F: FnOnce() + Send + 'static
  29. {
  30. let job = Box::new(f);
  31. self.sender.send(Message::NewJob(job)).unwrap();
  32. }
  33. // pub fn spawn<F, T>(f: F) -> JoinHandle<T>
  34. // where
  35. // F: FnOnce() -> T + Send + 'static,
  36. // T: Send + 'static
  37. // {
  38. // }
  39. }
  40. impl Drop for ThreadPool {
  41. fn drop(&mut self) {
  42. println!("Sending terminate message to all workers.");
  43. for _ in &mut self.workers {
  44. self.sender.send(Message::Terminate).unwrap();
  45. }
  46. println!("Shutting down all workers.");
  47. for worker in &mut self.workers {
  48. println!("Shutting down worker {}.", worker.id);
  49. if let Some(thread) = worker.thread.take() {
  50. thread.join().unwrap();
  51. }
  52. }
  53. }
  54. }
  55. struct Worker {
  56. id: usize,
  57. thread: Option<thread::JoinHandle<()>>,
  58. }
  59. impl Worker {
  60. fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Message>>>) ->
  61. Worker {
  62. let thread = thread::spawn(move ||{
  63. loop {
  64. let message = receiver.lock().unwrap().recv().unwrap();
  65. match message {
  66. Message::NewJob(job) => {
  67. println!("Worker {} got a job; executing.", id);
  68. job();
  69. },
  70. Message::Terminate => {
  71. println!("Worker {} was told to terminate.", id);
  72. break;
  73. },
  74. }
  75. }
  76. });
  77. Worker {
  78. id,
  79. thread: Some(thread),
  80. }
  81. }
  82. }