use std::sync::Arc;
use core_affinity::CoreId;
use crossbeam::atomic::AtomicCell;
use super::TaskExecutor;
pub struct ThreadPoolConstNum<const N: usize> {
thread: [TaskExecutor; N],
cur_run_core: AtomicCell<usize>,
}
impl<const N: usize> ThreadPoolConstNum<N> {
pub fn new() -> Self {
let use_cores = super::use_last_core2("ThreadPoolConstNum", N);
let mut threads = vec![];
for core_id in &use_cores {
threads.push(TaskExecutor::new(CoreId { id: *core_id }, 49));
}
ThreadPoolConstNum {
thread: threads
.try_into()
.expect("ThreadPoolLiteNum threads.try_into()"),
cur_run_core: 0.into(),
}
}
pub fn spawn<F>(&self, f: F)
where
F: FnOnce(),
F: Send + 'static,
{
let cur_index = self.cur_run_core.fetch_add(1);
self.thread[cur_index % N].spawn(|_| f());
if cur_index >= usize::MAX - N {
self.cur_run_core.store(0);
}
}
pub fn spawn_with_idx<F>(&self, f: F, thread_idx: usize)
where
F: FnOnce(),
F: Send + 'static,
{
self.thread[thread_idx].spawn(|_| f());
self.cur_run_core.store(thread_idx);
}
pub fn thread_count(&self) -> usize {
N
}
}
pub fn _test_ThreadPoolConstNum(test_count: u128) {
println!("------------------------start------------------------");
let pool = ThreadPoolConstNum::<5>::new();
std::thread::sleep(std::time::Duration::from_millis(200));
let com_time = Arc::new(AtomicCell::new(0_u128));
for _ in 0..test_count {
let com_time = com_time.clone();
let now = std::time::Instant::now();
pool.spawn(move || {
com_time.fetch_add(now.elapsed().as_nanos());
});
}
println!("------------------------ThreadPoolConstNum 任务提交完成------------------------");
std::thread::sleep(std::time::Duration::from_secs(1));
println!(
"ThreadPoolConstNum 线程开启平均耗时: {} ns",
com_time.load() as f64 / test_count as f64
);
}