Evgenii Legotckoi
28 грудня 2018 р. 20:09

Boost - виконання періодичних завдань за допомогою boost::thread

Пропоную написати невелику консольну програму, яка через рівні проміжки часу виконуватиме одне завдання.

Наприклад, програма запускається і робить 10 проб протягом 10 секунд, програма буде виводити інформацію про кількість зворотного відліку в консоль.

Програма працюватиме в такий спосіб.

Виконання періодичного завдання в консольному додатку


Структура проекту

У проекті використовується система складання CMake, тому структура проекту буде наступною.

Структура проекту PeriodicTask

CMakeLists.txt

Ось стандартна конфігурація CMake для збирання проекту.

  1. cmake_minimum_required (VERSION 3.8)
  2.  
  3. project(Periodic)
  4.  
  5. set(CMAKE_CXX_STANDARD 17)
  6. set(Boost_USE_STATIC_LIBS ON)
  7.  
  8. find_package(Boost 1.68 REQUIRED COMPONENTS thread)
  9.  
  10. set(SOURCE_FILES
  11. Periodic/main.cpp
  12. Periodic/PeriodicTask.cpp)
  13.  
  14. SET(HEADER_FILES
  15. Periodic/PeriodicTask.h)
  16.  
  17. if(Boost_FOUND)
  18. include_directories(${Boost_INCLUDE_DIRS})
  19. add_executable(Periodic ${SOURCE_FILES} ${HEADER_FILES})
  20. target_link_libraries(Periodic ${Boost_LIBRARIES})
  21. endif()

PeriodicTask.h

Заголовний файл періодичного завдання.

У найпростішому випадку для створення класу періодичного завдання нам знадобиться:

  • Тригерний період
  • об'єкт std::function для зберігання завдання
  • змінна bool для зупинки та запуску завдання. В даному прикладі ми не зупинятимемо завдання, але якщо додати методи run/stop, то реалізувати це цілком можливо.
  • boost::thread - потік, без якого цей функціонал не може бути реалізований
  1. #pragma once
  2.  
  3. #include <boost/thread.hpp>
  4. #include <boost/chrono.hpp>
  5. #include <functional>
  6. #include <atomic>
  7.  
  8. class PeriodicTask
  9. {
  10. public:
  11. explicit PeriodicTask(const boost::chrono::milliseconds &period, const std::function<void()> &func);
  12.  
  13. virtual ~PeriodicTask();
  14.  
  15. private:
  16. boost::chrono::milliseconds m_period; // Task period
  17. std::function<void()> m_func; // The function that will perform the periodic task
  18. 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
  19. boost::thread m_thread; // Task thread
  20. };

PeriodicTask.cpp

  1. #include "PeriodicTask.h"
  2.  
  3. PeriodicTask::PeriodicTask(const boost::chrono::milliseconds &period, const std::function<void()> &func) :
  4. m_period(period),
  5. m_func(func),
  6. m_running(true)
  7. {
  8. // Create a stream object to perform a periodic task.
  9. m_thread = boost::thread([this]
  10. {
  11. while (m_running)
  12. {
  13. // To perform a task with a specific period, immerse the stream in a dream after each task execution.
  14. boost::this_thread::sleep_for(m_period);
  15. if (m_running)
  16. {
  17. // perform the task
  18. m_func();
  19. }
  20. }
  21. });
  22. }
  23.  
  24. PeriodicTask::~PeriodicTask()
  25. {
  26. // When destroying an object with a periodic task
  27. m_running = false;
  28. // interrupt the flow, otherwise the program will not release system resources until the flow comes out of sleep
  29. // this is critical if the trigger period of the task is measured in tens of seconds and more
  30. m_thread.interrupt();
  31. m_thread.join();
  32. }

main.cpp

Файл із основною функцією. Коли ми створюємо об'єкт періодичного завдання, ми поміщаємо до нього лямбда-функцію як завдання, як найпростіший спосіб вказати, яку роботу потрібно виконати.

  1. #include "PeriodicTask.h" // We connect the class header file to perform periodic tasks.
  2.  
  3. #include <iostream>
  4.  
  5. int main(int argc, const char* argv[])
  6. {
  7. std::cout << "Start program" << std::endl;
  8. int count = 0;
  9. // Create a periodic task with a period of 1 second
  10. PeriodicTask p(boost::chrono::seconds{ 1 }, [&count]() {
  11. // Display the counter and increment it by one.
  12. std::cout << count++ << std::endl;
  13. });
  14.  
  15. // Stop the main program flow for 10 seconds so that the periodic task can work 10 times.
  16. boost::this_thread::sleep_for(boost::chrono::seconds{ 10 });
  17. std::cout << "End program" << std::endl;
  18. return 0;
  19. }

Висновок

На закінчення додаю архів із проектом.

Periodic.zip Periodic.zip

Рекомендовані статті на цю тему

По статті запитували0питання

1

Вам це подобається? Поділіться в соціальних мережах!

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
  • Останні коментарі
  • Evgenii Legotckoi
    16 квітня 2025 р. 17:08
    Благодарю за отзыв. И вам желаю всяческих успехов!
  • IscanderChe
    12 квітня 2025 р. 17:12
    Добрый день. Спасибо Вам за этот проект и отдельно за ответы на форуме, которые мне очень помогли в некоммерческих пет-проектах. Профессиональным программистом я так и не стал, но узнал мно…
  • AK
    01 квітня 2025 р. 11:41
    Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
  • Evgenii Legotckoi
    09 березня 2025 р. 21:02
    К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
  • VP
    09 березня 2025 р. 16:14
    Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…