I'm trying to write simple ScheduledExecutorService. I have a class:
class ScheduledExecutor {
public:
typedef size_t TaskID;
public:
explicit ScheduledExecutor(size_t);
~ScheduledExecutor();
ScheduledExecutor(ScheduledExecutor const &) = delete;
ScheduledExecutor(ScheduledExecutor &&) = delete;
ScheduledExecutor & operator = (ScheduledExecutor const &) = delete;
ScheduledExecutor & operator = (ScheduledExecutor &&) = delete;
template<typename Fn>
TaskID ScheduleDelayedTask(
Fn && fn, std::chrono::milliseconds delay = 0);
template<typename Fn>
TaskID SchedulePeriodicTask(
Fn && fn, std::chrono::milliseconds,
std::chrono::milliseconds period);
.
.
.
private:
std::vector< std::thread > workers;
std::queue< std::function<void()> > tasks;
std::mutex queue_mutex;
std::condition_variable condition;
bool stop;
};
I'm implemented some methods:
inline ScheduledExecutor::ScheduledExecutor(size_t threadPoolSize = 10) : stop(false) {
for (size_t i = 0; i < threadPoolSize; ++i) {
workers.emplace_back(
[this]
{
for (;;) {
std::function<void()> task;
{
std::unique_lock<std::mutex> lock(this->queue_mutex);
this->condition.wait(lock,
[this]{ return this->stop || !this->tasks.empty(); });
if (this->stop && this->tasks.empty())
return;
task = std::move(this->tasks.front());
this->tasks.pop();
}
task();
}
});
}
}
template<typename Fn>
ScheduledExecutor::TaskID ScheduledExecutor::ScheduleDelayedTask(
Fn && fn, std::chrono::milliseconds delay) {
{
std::unique_lock<std::mutex> lock(queue_mutex);
if (stop)
throw std::runtime_error("enqueue on stopped ThreadPool");
tasks.push(std::function<void()>(fn));
}
condition.notify_one();
return 0;
}
The first question is: "How to add delay to first method(TaskID ScheduleDelayedTask)? I have an idea to wrape this function in anonymous thread (inside the method) and sleep it for delay seconds before "condition.notify_one();". But it is not a good way (if we have 10000 tasks with long delay? In result we will have 10000 threads which do nothing). Gimme a good way to solve this problem please.
Aucun commentaire:
Enregistrer un commentaire