ThreadSchedule provides a powerful scheduling system for running tasks at specific times or periodically.
Features
- ✅ One-time scheduled tasks - Run a task after a delay or at a specific time
- ✅ Periodic tasks - Run tasks repeatedly at fixed intervals
- ✅ Cancellable tasks - Cancel scheduled tasks before they execute
- ✅ Flexible execution - Choose from ThreadPool (default), HighPerformancePool, or FastThreadPool
- ✅ Thread-safe - Safe to use from multiple threads
Quick Start
using namespace threadschedule;
int main() {
ScheduledThreadPool scheduler(4);
auto handle = scheduler.schedule_after(std::chrono::seconds(5), []() {
std::cout << "Task executed!\n";
});
}
static void cancel(ScheduledTaskHandle &handle)
Modern C++23 Thread Scheduling Library.
API Reference
Pool Types
ThreadSchedule provides three variants of the scheduled pool:
ScheduledThreadPool scheduler(4);
ScheduledHighPerformancePool scheduler_hp(4);
ScheduledFastThreadPool scheduler_fast(4);
Thread pool with support for scheduled and periodic tasks.
Constructor
ScheduledThreadPool(size_t worker_threads = std::thread::hardware_concurrency());
Create a scheduled thread pool with the specified number of worker threads.
Scheduling Methods
schedule_after()
Handle for scheduled tasks that can be used to cancel them.
Schedule a task to run after a delay.
Example:
auto handle = scheduler.schedule_after(std::chrono::seconds(10), []() {
std::cout << "Executed after 10 seconds\n";
});
schedule_at()
Schedule a task to run at a specific time point.
Example:
auto future_time = std::chrono::steady_clock::now() + std::chrono::minutes(5);
auto handle = scheduler.schedule_at(future_time, []() {
std::cout << "Executed at specific time\n";
});
schedule_periodic()
Schedule a task to run periodically at fixed intervals. The task runs immediately and then repeats.
Example:
auto handle = scheduler.schedule_periodic(std::chrono::seconds(1), []() {
std::cout << "Runs every second\n";
});
schedule_periodic_after()
auto schedule_periodic_after(Duration initial_delay, Duration interval, Task task)
Schedule a task to run periodically with an initial delay.
Example:
auto handle = scheduler.schedule_periodic_after(
std::chrono::seconds(5),
std::chrono::seconds(1),
[]() {
std::cout << "Periodic task\n";
}
);
Cancellation
Cancel a scheduled task before it executes. For periodic tasks, this stops future executions.
Example:
auto handle = scheduler.schedule_periodic(std::chrono::seconds(1), task);
Status Methods
[[nodiscard]] auto scheduled_count() const -> size_t;
Get the number of scheduled tasks (including periodic tasks).
[[nodiscard]] auto thread_pool() -> PoolType&;
Access the underlying thread pool for direct task submission. The type depends on the pool variant used.
Configuration
auto configure_threads(std::string const& name_prefix,
SchedulingPolicy policy = SchedulingPolicy::OTHER,
Thread priority wrapper with validation.
Configure worker thread properties (names, scheduling policy, priority).
Complete Example
#include <chrono>
#include <iostream>
using namespace threadschedule;
using namespace std::chrono_literals;
int main() {
ScheduledThreadPool scheduler(4);
scheduler.configure_threads("scheduler");
auto delayed_task = scheduler.schedule_after(2s, []() {
std::cout << "Delayed task executed\n";
});
auto future_time = std::chrono::steady_clock::now() + 5s;
auto timed_task = scheduler.schedule_at(future_time, []() {
std::cout << "Timed task executed\n";
});
int counter = 0;
auto periodic = scheduler.schedule_periodic(1s, [&counter]() {
counter++;
std::cout << "Periodic task #" << counter << "\n";
if (counter >= 5) {
}
});
std::this_thread::sleep_for(6s);
scheduler.shutdown();
return 0;
}
Use Cases
Periodic Monitoring
auto monitor = scheduler.schedule_periodic(std::chrono::seconds(30), []() {
check_system_health();
});
Delayed Cleanup
auto cleanup = scheduler.schedule_after(std::chrono::minutes(5), []() {
cleanup_temp_files();
});
Timed Reminders
auto reminder_time = calculate_reminder_time();
auto reminder = scheduler.schedule_at(reminder_time, []() {
send_notification("Time for your meeting!");
});
Background Jobs
auto backup = scheduler.schedule_periodic(std::chrono::hours(24), []() {
backup_database();
});
Choosing the Right Pool
ThreadPool (Default)
- Use when: General-purpose scheduling (< 1k tasks/sec)
- Pros: Simple, low overhead, easy to debug
- Best for: Timers, periodic maintenance, background jobs
HighPerformancePool
- Use when: High-frequency task scheduling (10k+ tasks/sec)
- Pros: Work-stealing, optimal for many small tasks
- Best for: Real-time systems, high-throughput scenarios
FastThreadPool
- Use when: Medium-frequency scheduling (1k-10k tasks/sec)
- Pros: Single queue, balanced performance
- Best for: Batch processing, moderate workloads
Example:
ScheduledThreadPool scheduler(2);
ScheduledHighPerformancePool scheduler_hp(8);
Performance Notes
- The scheduler uses a single scheduling thread and a worker pool for execution
- Task throughput depends on the chosen pool type
- Cancellation is lightweight and doesn't require task execution
- Periodic tasks automatically reschedule after execution
Advanced Example: Multiple Pool Types
#include <iostream>
using namespace threadschedule;
using namespace std::chrono_literals;
int main() {
ScheduledThreadPool maintenance(2);
maintenance.configure_threads("maintenance");
auto cleanup = maintenance.schedule_periodic(1h, []() {
cleanup_temp_files();
});
auto backup = maintenance.schedule_periodic(24h, []() {
backup_database();
});
ScheduledHighPerformancePool
realtime(8);
realtime.thread_pool().distribute_across_cpus();
auto monitor =
realtime.schedule_periodic(100ms, []() {
monitor_system_health();
});
auto metrics =
realtime.schedule_periodic(1s, []() {
collect_metrics();
});
std::this_thread::sleep_for(10s);
maintenance.shutdown();
}
auto realtime() -> ThreadProfile
Highest priority profile. Uses FIFO on Linux (if permitted), falls back to OTHER on Windows.
Thread Safety
All methods are thread-safe and can be called from multiple threads:
ScheduledThreadPool scheduler(4);
auto handle1 = scheduler.schedule_after(1s, task1);
auto handle2 = scheduler.schedule_periodic(2s, task2);
See Also