Skip to content

Instantly share code, notes, and snippets.

@Milerius
Created May 31, 2018 22:38
Show Gist options
  • Save Milerius/b20a00b333d0481095b8d0d72c527199 to your computer and use it in GitHub Desktop.
Save Milerius/b20a00b333d0481095b8d0d72c527199 to your computer and use it in GitHub Desktop.
class ThreadPool : private utils::NonCopyable
{
public:
explicit ThreadPool(size_t nbThreads = 5) noexcept
{
_threads.reserve(nbThreads);
for (size_t i = 0; i < nbThreads; ++i) {
_threads.emplace_back(&ThreadPool::__threadLoop, this);
}
}
virtual ~ThreadPool() noexcept
{
_working = false;
_tasks.deactivate();
for (auto &cur : _threads) {
if (cur.joinable()) {
cur.join();
}
}
}
private:
void __threadLoop() noexcept
{
while (_working) {
ITask *todo;
if (_tasks.pop(todo)) {
todo->execute();
delete todo;
}
}
}
class ITask
{
public:
virtual ~ITask() = default;
virtual void execute() = 0;
};
template <typename FuncT>
class Task : public ITask
{
public:
Task(FuncT &&func) noexcept : _func(std::forward<FuncT>(func))
{
}
void execute() override
{
_func();
}
private:
FuncT _func;
};
public:
template <typename FuncT, typename ...Args>
auto addWork(FuncT &&func, Args &&...args)
{
auto boundFunc = std::bind(std::forward<FuncT>(func), std::forward<Args>(args)...);
using RetType = std::invoke_result_t<decltype(boundFunc)>;
using PkgedTask = std::packaged_task<RetType()>;
PkgedTask task{std::move(boundFunc)};
auto ret = task.get_future();
_tasks.push(new Task<PkgedTask>(std::move(task)));
return ret;
}
private:
std::atomic_bool _working{true};
TSQueue<ITask *> _tasks;
std::vector<std::thread> _threads;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment