单队列
#include "safe_queue.h"
#include <functional>
#include <thread>
#include <vector>
using WorkItem = std::function<void()>;
class SimplePool {
public:
explicit SimplePool(size_t threads = std::thread::hardware_concurrency()) {
for (size_t i = 0; i < threads; ++i)
workers_.emplace_back([this] {
for (;;) {
std::function<void()> task;
if (!queue_.pop(task)) {
return;
}
if (task) {
task();
}
}
});
}
void enqueue(WorkItem item) { queue_.push(std::move(item)); }
~SimplePool() {
queue_.stop();
for (auto &thd : workers_) {
thd.join();
}
}
private:
Queue<WorkItem> queue_;
std::vector<std::thread> workers_;
};
多队列
#pragma once
#include "safe_queue.h"
#include <cassert>
#include <functional>
#include <thread>
#include <vector>
class MultiplePool {
public:
explicit MultiplePool(
size_t thread_num = std::thread::hardware_concurrency())
: queues_(thread_num), thread_num_(thread_num) {
auto worker = [this](size_t id) {
while (true) {
std::function<void()> task{};
if (!queues_[id].pop(task)) {
break;
}
if (task) {
task();
}
}
};
workers_.reserve(thread_num);
for (size_t i = 0; i < thread_num; i++) {
workers_.emplace_back(worker, i);
}
}
int schedule_by_id(std::function<void()> fn, size_t id = -1) {
if (fn == nullptr) {
return -1;
}
if (id == -1) {
id = rand() % thread_num_;
queues_[id].push(std::move(fn));
} else {
assert(id < thread_num_);
queues_[id].push(std::move(fn));
}
return 0;
}
~MultiplePool() {
for (auto &queue : queues_) {
queue.stop();
}
for (auto &worker : workers_) {
worker.join();
}
}
private:
std::vector<Queue<std::function<void()>>> queues_;
size_t thread_num_;
std::vector<std::thread> workers_;
};