Last active
April 20, 2021 15:39
-
-
Save wangzhankun/9954c4913cd30c95d502b4ff9c47739e to your computer and use it in GitHub Desktop.
线程池 thread_poll
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <mutex> | |
#include <condition_variable> | |
#include <functional> | |
#include <queue> | |
#include <thread> | |
class fixed_thread_pool | |
{ | |
private: | |
struct data | |
{ | |
std::mutex mtx_; | |
std::condition_variable cond_; | |
bool is_shutdown_ = false; | |
std::queue<std::function<void()>> tasks_; | |
}; | |
std::shared_ptr<data> data_; | |
public: | |
explicit fixed_thread_pool(size_t thread_count) | |
: data_(std::make_shared<data>()) | |
{ | |
for (size_t i = 0; i < thread_count; ++i) | |
{ | |
std::thread([data = data_] { | |
std::unique_lock<std::mutex> lk(data->mtx_); | |
for (;;) | |
{ | |
if (!data->tasks_.empty()) | |
{ | |
auto current = std::move(data->tasks_.front()); | |
data->tasks_.pop(); | |
lk.unlock(); | |
current(); | |
lk.lock(); | |
} | |
else if (data->is_shutdown_) | |
{ | |
break; | |
} | |
else | |
{ | |
data->cond_.wait(lk); | |
} | |
} | |
}).detach(); | |
} | |
} | |
fixed_thread_pool() = default; | |
fixed_thread_pool(fixed_thread_pool &&) = default; | |
~fixed_thread_pool() | |
{ | |
if ((bool)data_) | |
{ | |
{ | |
std::lock_guard<std::mutex> lk(data_->mtx_); | |
data_->is_shutdown_ = true; | |
} | |
data_->cond_.notify_all(); | |
} | |
} | |
template <class F> | |
void execute(F &&task) | |
{ | |
{ | |
std::lock_guard<std::mutex> lk(data_->mtx_); | |
data_->tasks_.emplace(std::forward<F>(task)); | |
} | |
data_->cond_.notify_one(); | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::thread; | |
use std::sync::mpsc; | |
use std::sync::Arc; | |
use std::sync::Mutex; | |
pub struct ThreadPool{ | |
workers: Vec<Worker>, | |
sender: mpsc::Sender<Job>, | |
} | |
type Job = Box<dyn FnOnce() + Send + 'static>; | |
impl ThreadPool{ | |
/// Create a new ThreadPool | |
/// | |
/// The size is the number of threads in the pool. | |
/// | |
/// # Panics | |
/// | |
/// The `new` function will panic if the size is zero | |
pub fn new(size: usize) -> ThreadPool{ | |
assert!(size > 0); | |
let (sender, receiver) = mpsc::channel(); | |
let receiver = Arc::new(Mutex::new(receiver)); | |
let mut workers = Vec::with_capacity(size); | |
for id in 0..size { | |
workers.push(Worker::new(id, Arc::clone(&receiver))); | |
} | |
ThreadPool {workers, sender} | |
} | |
pub fn execute<F>(&self, f: F) | |
where F: FnOnce() + Send + 'static, | |
{ | |
let job = Box::new(f); | |
self.sender.send(job).unwrap(); | |
} | |
} | |
struct Worker{ | |
id: usize, | |
thread: thread::JoinHandle<()>, | |
} | |
impl Worker{ | |
fn new(id: usize, receiver: Arc<Mutex<mpsc::Receiver<Job>>>)->Worker{ | |
let thread = thread::spawn(move || loop{ | |
// while let Ok(job) = receiver.lock().unwrap().recv(){ | |
// println!("Worker {} got a job; executing.", id); | |
// job(); | |
// } | |
let job = receiver.lock().unwrap().recv().unwrap(); | |
println!("Worker {} got a job; executing.", id); | |
job(); | |
}); | |
Worker{id, thread} | |
} | |
} | |
Author
wangzhankun
commented
Apr 20, 2021
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment