也来写个线程池
#include <iostream>
#include <vector>
#include <memory>
#include <thread>
#include <mutex>
#include <queue>
#include <condition_variable>
#include <functional>
#include <chrono>
template <class T>
class Queue {
public:
explicit Queue(uint32_t size = 2000) : queueSize_(size) {}
void Push(T& data)
{
std::unique_lock<std::mutex> lk(mtx_);
if (IsFull()) {
notFullCondVar_.wait(lk, [&] { return !IsEmpty() || quit_; });
}
if (!IsFull()) {
queue_.push(data);
notEmptyCondVar_.notify_all();
}
}
bool Pop(T& data)
{
std::unique_lock<std::mutex> lk(mtx_);
if (IsEmpty()) {
notEmptyCondVar_.wait(lk, [&] { return !IsFull() || quit_; });
}
if (!IsEmpty()) {
data = queue_.front();
queue_.pop();
notFullCondVar_.notify_all();
return true;
}
return false;
}
void Quit() { quit_ = true; }
bool IsFull() { return queue_.size() == queueSize_; }
bool IsEmpty() { return queue_.empty(); }
private:
uint32_t queueSize_;
std::queue<T> queue_;
std::mutex mtx_;
std::condition_variable notFullCondVar_;
std::condition_variable notEmptyCondVar_;
bool quit_ = false;
};
struct Task {
std::function<void(void *)> process_;
void *data;
};
void Process(void *data)
{
std::cout << "process task " << (uint32_t)(uintptr_t)data << std::endl;
}
class ThreadPool {
public:
explicit ThreadPool(uint32_t num = 4) : threadNum_(num) {}
void Start()
{
working_ = true;
for (auto i = 0; i < threadNum_; i++) {
pool_.push_back(std::thread(std::bind(&ThreadPool::Work, this)));
}
}
void Stop()
{
que_.Quit();
working_ = false;
for (auto i = 0; i < threadNum_; i++) {
if (pool_[i].joinable()) {
pool_[i].join();
}
}
}
void Work()
{
std::shared_ptr<Task> task;
while (working_) {
auto ret = que_.Pop(task);
if (ret == false) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
continue;
}
task->process_(task->data);
}
}
void Push(std::shared_ptr<Task> task)
{
que_.Push(task);
}
private:
uint32_t threadNum_;
std::vector<std::thread> pool_;
Queue<std::shared_ptr<Task>> que_;
bool working_;
};
int main() {
ThreadPool tp(4);
tp.Start();
uint32_t i = 0;
while (1) {
std::shared_ptr<Task> task = std::make_shared<Task>();
task->process_ = Process;
task->data = (void *)(uintptr_t)i;
i++;
tp.Push(task);
if (i == 10) {
break;
}
}
std::this_thread::sleep_for(std::chrono::seconds(10));
tp.Stop();
return 0;
}