From 150a76de0eaa530a14d5668284b9fef6035c3344 Mon Sep 17 00:00:00 2001 From: abbycin Date: Sat, 13 Jan 2024 13:23:22 +0800 Subject: [PATCH] turn into lib --- Cargo.lock | 237 ---------------------------------------------------- Cargo.toml | 6 -- src/lib.rs | 77 ++++++++++++----- src/main.rs | 19 ----- 4 files changed, 56 insertions(+), 283 deletions(-) delete mode 100644 src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 9efd6f1..d9f57f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,243 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - -[[package]] -name = "bitflags" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" - -[[package]] -name = "env_logger" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "hermit-abi" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "is-terminal" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys", -] - -[[package]] -name = "libc" -version = "0.2.152" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" - -[[package]] -name = "linux-raw-sys" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "memchr" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" - -[[package]] -name = "regex" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - -[[package]] -name = "rustix" -version = "0.38.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - [[package]] name = "threadpool" version = "0.1.0" -dependencies = [ - "env_logger", - "log", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" diff --git a/Cargo.toml b/Cargo.toml index 8913602..2651229 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,9 +2,3 @@ name = "threadpool" version = "0.1.0" edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -env_logger = "0.10.1" -log = "0.4.20" diff --git a/src/lib.rs b/src/lib.rs index 67c2fdb..76a33f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ use std::{ - collections::LinkedList, + collections::VecDeque, sync::{ atomic::{AtomicBool, AtomicUsize, Ordering}, Arc, Mutex, @@ -9,11 +9,9 @@ use std::{ time::Duration, }; -use log::info; - pub struct ThreadPool { thrd: Vec>>, - queue: Arc>>>>, + queue: Arc>>>>, index: Arc, cnt: Arc, stop: Arc, @@ -25,7 +23,7 @@ impl ThreadPool { pub fn new(n: u8) -> Self { let mut w = Vec::new(); for _ in 0..n { - w.push(Mutex::new(LinkedList::new())); + w.push(Mutex::new(VecDeque::new())); } let mut r = ThreadPool { thrd: vec![], @@ -43,26 +41,23 @@ impl ThreadPool { cnt.fetch_add(1, Ordering::SeqCst); let n = n as usize; let lock = &q[id % n]; - let mut l = LinkedList::new(); - let process = |l: &mut LinkedList>| { + let mut l = VecDeque::new(); + let process = |l: &mut VecDeque>| { while !l.is_empty() { let t = l.pop_front().unwrap(); t(); } }; while !stop.load(Ordering::SeqCst) { - info!("thread {}", id); thread::sleep(Duration::from_micros(500)); { let mut tmp = lock.lock().unwrap(); l.append(&mut tmp); } - info!("thread {} working", id); process(&mut l); } let mut l = lock.lock().unwrap(); process(&mut l); - info!("thread {} exit", id); }))); } r @@ -71,10 +66,8 @@ impl ThreadPool { pub fn push(&mut self, t: impl FnOnce() + Send + 'static) { let idx = self.index.fetch_add(1, Ordering::SeqCst) % self.queue.len(); let lock = &self.queue[idx]; - info!("add task to thread {}", idx); let l = &mut lock.lock().unwrap(); l.push_back(Box::new(t)); - info!("notify thread {}", idx); } pub fn started(&self) -> bool { @@ -83,22 +76,64 @@ impl ThreadPool { pub fn stop(&mut self) { self.stop.store(true, Ordering::SeqCst); - let mut i = 0; for lock in self.queue.as_ref() { let _ = lock.lock(); - info!("notify exit {}", i); - i += 1; } } + + pub fn join(&mut self) { + if !self.thrd.is_empty() { + for task in &mut self.thrd { + if let Some(t) = task.take() { + let id = t.thread().id(); + t.join().expect(&format!("can't join thrd {:?}", id)); + } + } + } + self.thrd.clear(); + } } impl Drop for ThreadPool { fn drop(&mut self) { - for task in &mut self.thrd { - if let Some(t) = task.take() { - let id = t.thread().id(); - t.join().expect(&format!("can't join thrd {:?}", id)); - } - } + self.join(); + } +} + +#[cfg(test)] +mod tests { + use std::{ + sync::{ + atomic::{AtomicU8, Ordering}, + Arc, + }, + thread, + }; + + use crate::ThreadPool; + + #[test] + fn test_thread_pool() { + let mut pool = ThreadPool::new(4); + let cnt = Arc::new(AtomicU8::new(0)); + let n = 10; + + while !pool.started() { + thread::yield_now(); + } + + for _ in 0..n { + let c = cnt.clone(); + pool.push(move || { + let i = c.fetch_add(1, Ordering::SeqCst); + println!("process task {i} in {:?}", thread::current().id()); + }); + } + + pool.stop(); + pool.join(); + + println!("cnt => {}", cnt.fetch_add(0, Ordering::SeqCst)); + assert_eq!(cnt.load(Ordering::SeqCst), n); } } diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 77e8de5..0000000 --- a/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -use threadpool::*; - -fn main() { - // std::env::set_var("RUST_LOG", "trace"); - std::env::set_var("RUST_LOG", "notice"); - env_logger::init(); - let mut pool = ThreadPool::new(10); - - // while !pool.started() { - // std::thread::yield_now(); - // } - for i in 0..12 { - pool.push(move || { - println!("task {:?} => {:?}", i, std::thread::current().id()); - }) - } - - pool.stop(); -}