2016-08-02 01:46:05 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
#include <thread>
|
|
|
|
#include <mutex>
|
|
|
|
#include <condition_variable>
|
|
|
|
#include <functional>
|
|
|
|
#include <queue>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
|
|
/** Very simple thread pool similar to boost::threadpool.
|
|
|
|
* Advantages:
|
|
|
|
* - catches exceptions and rethrows on wait.
|
|
|
|
*/
|
|
|
|
|
|
|
|
class ThreadPool
|
|
|
|
{
|
|
|
|
private:
|
2017-04-01 07:20:54 +00:00
|
|
|
using Job = std::function<void()>;
|
2016-08-02 01:46:05 +00:00
|
|
|
|
|
|
|
public:
|
2017-04-01 07:20:54 +00:00
|
|
|
/// Size is constant, all threads are created immediately.
|
|
|
|
ThreadPool(size_t m_size);
|
2016-08-13 05:29:53 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
/// Add new job. Locks until free thread in pool become available or exception in one of threads was thrown.
|
|
|
|
/// If an exception in some thread was thrown, method silently returns, and exception will be rethrown only on call to 'wait' function.
|
|
|
|
void schedule(Job job);
|
2016-08-13 05:29:53 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
/// Wait for all currently active jobs to be done.
|
|
|
|
/// You may call schedule and wait many times in arbitary order.
|
|
|
|
/// If any thread was throw an exception, first exception will be rethrown from this method,
|
|
|
|
/// and exception will be cleared.
|
|
|
|
void wait();
|
2016-08-13 05:29:53 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
/// Waits for all threads. Doesn't rethrow exceptions (use 'wait' method to rethrow exceptions).
|
|
|
|
/// You should not destroy object while calling schedule or wait methods from another threads.
|
|
|
|
~ThreadPool();
|
2016-08-02 01:46:05 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
size_t size() const { return m_size; }
|
2016-08-02 01:46:05 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
/// Returns number of active jobs.
|
|
|
|
size_t active() const;
|
2016-08-02 01:46:05 +00:00
|
|
|
|
|
|
|
private:
|
2017-04-01 07:20:54 +00:00
|
|
|
mutable std::mutex mutex;
|
|
|
|
std::condition_variable has_free_thread;
|
|
|
|
std::condition_variable has_new_job_or_shutdown;
|
2016-08-02 01:46:05 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
const size_t m_size;
|
|
|
|
size_t active_jobs = 0;
|
|
|
|
bool shutdown = false;
|
2016-08-02 01:46:05 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
std::queue<Job> jobs;
|
|
|
|
std::vector<std::thread> threads;
|
|
|
|
std::exception_ptr first_exception;
|
2016-08-13 05:29:53 +00:00
|
|
|
|
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
void worker();
|
2016-08-02 01:46:05 +00:00
|
|
|
};
|
|
|
|
|