template<typename PoolType = ThreadPool>
class threadschedule::ScheduledThreadPoolT< PoolType >
Thread pool augmented with delayed and periodic task scheduling.
Non-copyable, non-movable. Combines a dedicated scheduler thread with an underlying PoolType (default: ThreadPool) that does the actual work.
- How task execution works
- The pool owns a single scheduler thread that runs an internal loop (scheduler_loop). Scheduled tasks are stored in a std::multimap sorted by their next_run time point. The scheduler thread sleeps (via condition_variable::wait / wait_until) until the earliest task is due. When a task becomes due, the scheduler thread:
- Removes it from the multimap.
- Checks if the task has been cancelled (via the atomic flag). If cancelled, the task is discarded.
- Submits the task to the underlying PoolType via pool_.submit(). From this point on, the task follows the execution rules of the underlying pool (see ThreadPool, FastThreadPool, or HighPerformancePool documentation).
- For periodic tasks, the scheduler immediately re-inserts the task into the multimap with next_run += interval. This means the next execution is timed from the scheduled time, not from when the task actually finishes.
- Execution guarantees
- Every successfully scheduled task (schedule_after/schedule_at/ schedule_periodic returned a handle) is guaranteed to eventually execute, unless it is cancelled or shutdown() is called before it becomes due.
- Tasks are stored in a std::multimap keyed by time point. When multiple tasks share the same due time, they are dispatched in insertion order (guaranteed by std::multimap since C++11).
- Tasks that are already due and submitted to the underlying pool before shutdown() will still execute (the pool drains its queue).
- Tasks that are not yet due at the time of shutdown() will NOT execute. The scheduler thread exits immediately on shutdown, so future-scheduled tasks are lost.
- Cancellation is cooperative: calling handle.cancel() sets an atomic flag. The scheduler checks this flag before submitting the task to the pool. Additionally, the pool-side wrapper checks the flag again right before calling the task. However, a task that is already running will NOT be interrupted by cancel().
- Periodic tasks repeat at a fixed interval, not a fixed rate. If a task takes longer than the interval, executions can pile up because the next run is computed from the previous scheduled time, not from when the task actually finishes.
- There is no returned std::future for scheduled tasks. If you need to observe the result, use the underlying pool directly via thread_pool().submit().
- Thread safety
- All schedule_* methods are thread-safe (protected by an internal mutex). cancel() on a ScheduledTaskHandle is also thread-safe (atomic). shutdown() is internally guarded and safe to call more than once.
- Lifetime
- The destructor calls shutdown(), which joins the scheduler thread and then shuts down the underlying pool. Can block if the pool still has running tasks.
- Copyability / movability
- Not copyable, not movable.
- Template Parameters
-
| PoolType | Thread pool used for task execution (default: ThreadPool). |
- See also
- ScheduledThreadPool, ScheduledHighPerformancePool, ScheduledFastThreadPool (convenience aliases)
Definition at line 132 of file scheduled_pool.hpp.