Evgenii Legotckoi
Evgenii Legotckoi28 декабря 2018 г. 9:09

Boost - выполнение периодических задач с использованием boost::thread

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

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

Программа будет работать следующим образом.

Выполнение периодический задачи в консольном приложении


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

В проекте используется система сборки CMake, поэтому структура проекта будет следующей.

PeriodicTask project structure

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;
}

Заключение

В заключение прилагаю архив с проектом.

Periodic.zip Periodic.zip

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
e
  • ehot
  • 31 марта 2024 г. 14:29

C++ - Тест 003. Условия и циклы

  • Результат:78баллов,
  • Очки рейтинга2
B

C++ - Тест 002. Константы

  • Результат:16баллов,
  • Очки рейтинга-10
B

C++ - Тест 001. Первая программа и типы данных

  • Результат:46баллов,
  • Очки рейтинга-6
Последние комментарии
k
kmssr8 февраля 2024 г. 18:43
Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий Кононенко5 февраля 2024 г. 1:50
Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25 декабря 2023 г. 10:30
Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJo25 декабря 2023 г. 8:38
Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
Gvozdik18 декабря 2023 г. 21:01
Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Сейчас обсуждают на форуме
a
a_vlasov14 апреля 2024 г. 6:41
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
Павел Дорофеев
Павел Дорофеев14 апреля 2024 г. 2:35
QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
f
fastrex4 апреля 2024 г. 4:47
Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…
P
Pisych27 февраля 2023 г. 4:04
Как получить в массив значения из связанной модели? Спасибо, разобрался:))
AC
Alexandru Codreanu19 января 2024 г. 11:57
QML Обнулить значения SpinBox Доброго времени суток, не могу разобраться с обнулением значение SpinBox находящего в делегате. import QtQuickimport QtQuick.ControlsWindow { width: 640 height: 480 visible: tr…

Следите за нами в социальных сетях