Предлагаю написать небольшую консольную программу, которая через равные промежутки времени будет выполнять одну задачу.
Например, программа запускается и делает 10 проб в течение 10 секунд, при этом программа будет выводить информацию о количестве обратного отсчета в консоль.
Программа будет работать следующим образом.
Структура проекта
В проекте используется система сборки CMake, поэтому структура проекта будет следующей.
CMakeLists.txt
Вот стандартная конфигурация CMake для сборки проекта.
cmake_minimum_required (VERSION 3.8) project(Periodic) set(CMAKE_CXX_STANDARD 17) set(Boost_USE_STATIC_LIBS ON) find_package(Boost 1.68 REQUIRED COMPONENTS thread) set(SOURCE_FILES Periodic/main.cpp Periodic/PeriodicTask.cpp) SET(HEADER_FILES Periodic/PeriodicTask.h) if(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) add_executable(Periodic ${SOURCE_FILES} ${HEADER_FILES}) target_link_libraries(Periodic ${Boost_LIBRARIES}) endif()
PeriodicTask.h
Заголовочный файл периодической задачи.
В простейшем случае для создания класса периодической задачи нам потребуется:
- триггерный период
- объект std::function для хранения задачи
- переменная bool для остановки и запуска задачи. В данном примере мы не будем останавливать задачу, но если добавить методы run/stop, то реализовать это вполне возможно.
- boost::thread — поток, без которого этот функционал не может быть реализован
#pragma once #include <boost/thread.hpp> #include <boost/chrono.hpp> #include <functional> #include <atomic> class PeriodicTask { public: explicit PeriodicTask(const boost::chrono::milliseconds &period, const std::function<void()> &func); virtual ~PeriodicTask(); private: boost::chrono::milliseconds m_period; // Task period std::function<void()> m_func; // The function that will perform the periodic task std::atomic<bool> m_running; // A variable that indicates that the task is running, with the help of it you can stop the task in the future boost::thread m_thread; // Task thread };
PeriodicTask.cpp
#include "PeriodicTask.h" PeriodicTask::PeriodicTask(const boost::chrono::milliseconds &period, const std::function<void()> &func) : m_period(period), m_func(func), m_running(true) { // Create a stream object to perform a periodic task. m_thread = boost::thread([this] { while (m_running) { // To perform a task with a specific period, immerse the stream in a dream after each task execution. boost::this_thread::sleep_for(m_period); if (m_running) { // perform the task m_func(); } } }); } PeriodicTask::~PeriodicTask() { // When destroying an object with a periodic task m_running = false; // interrupt the flow, otherwise the program will not release system resources until the flow comes out of sleep // this is critical if the trigger period of the task is measured in tens of seconds and more m_thread.interrupt(); m_thread.join(); }
main.cpp
Файл с основной функцией. Когда мы создаем объект периодической задачи, мы помещаем в него лямбда-функцию как задачу, как самый простой способ указать, какую работу нужно выполнить.
#include "PeriodicTask.h" // We connect the class header file to perform periodic tasks. #include <iostream> int main(int argc, const char* argv[]) { std::cout << "Start program" << std::endl; int count = 0; // Create a periodic task with a period of 1 second PeriodicTask p(boost::chrono::seconds{ 1 }, [&count]() { // Display the counter and increment it by one. std::cout << count++ << std::endl; }); // Stop the main program flow for 10 seconds so that the periodic task can work 10 times. boost::this_thread::sleep_for(boost::chrono::seconds{ 10 }); std::cout << "End program" << std::endl; return 0; }
Заключение
В заключение прилагаю архив с проектом.