Политика конфиденциальностиКонтактыО сайтеОтзывыGitHubDonate
© EVILEG 2015-2018
Рекомендует хостинг
TIMEWEB

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

Boost, threads, chrono

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

Например, программа запускается и делает 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;   // Период срабатывания задачи
    std::function<void()> m_func;           // Функция, которая будет выполнять периодическую задачу
    std::atomic<bool> m_running;            // Переменная, которая указывает, что выполнение задачи запушено, с помощью неё можно в дальнейшем останавливать задачу
    boost::thread m_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)
{
    // Создаём объект потока для выполнения периодической задачи
    m_thread = boost::thread([this]
    {
        while (m_running)
        {
            // Для выполнения задачи с определённым периодом погружаем поток в сон после каждого выполнения задачи
            boost::this_thread::sleep_for(m_period);
            if (m_running)
            {
                // выполняем задачу
                m_func();
            }
        }
    });
}

PeriodicTask::~PeriodicTask()
{
    // При уничтожении объекта с периодической задачей
    m_running = false;
    // прерываем поток, иначе программа не освободит ресурсы системы, пока поток не выйдет из сна
    // это критично, если период срабатывания задачи измеряется десятками секунд и больше
    m_thread.interrupt();
    m_thread.join();
}

main.cpp

Файл с функцией main. Когда мы создаём объект периодической задачи, то мы помещаем в качестве задачи в него лямбда функцию, как наиболее простой способ указания, какую работу требуется выполнить.

#include "PeriodicTask.h" // Подключим заголовочный файл класса для выполнения периодических задач

#include <iostream>

int main(int argc, const char* argv[])
{
    std::cout << "Start program" << std::endl;
    int count = 0;
    // Создадим периодическую задачу с периодом 1 секунда
    PeriodicTask p(boost::chrono::seconds{ 1 }, [&count]() {
        // Выводим счётчик и увеличиваем его на единицу
        std::cout << count++ << std::endl;
    });

    // Остановим основной поток программы на 10 секунд, чтобы 10 раз успела отработать периодическая задача
    boost::this_thread::sleep_for(boost::chrono::seconds{ 10 });
    std::cout << "End program" << std::endl;
    return 0;
}

Заключение

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

Periodic.zip

Возврат 10% от суммы заказа отеля на Booking
Возврат 10% от суммы заказа отеля на Booking
Предлагаем ссылку с 10% возвратом от суммы заказа при бронировании отеля через Booking

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
IT
25 марта 2019 г. 17:32
Ilya The Engineer

Qt - Тест 001. Сигналы и слоты

  • Результат:5баллов,
  • Очки рейтинга-10
G
25 марта 2019 г. 8:34
GAG

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

  • Результат:41баллов,
  • Очки рейтинга-8
G
25 марта 2019 г. 8:25
GAG

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

  • Результат:66баллов,
  • Очки рейтинга-1
Последние комментарии
22 марта 2019 г. 12:32
Евгений Легоцкой

Ну может бибилотеки не те положили? У вас сборка для MinGW, а либы для MSVC.
ВН
22 марта 2019 г. 11:08
Волчонок Над-Пропастью

Из кьюта приложение не хочет запускаться, аварийно завершается, но каких-либо ошибок не выдаёт. Оно открывается, после нажатия "старт" зависает и завершается. Если не из кьюта запускать дебаг ...
21 марта 2019 г. 15:49
Евгений Легоцкой

серьезно? Эта ошибка 404 уже даже не относится к данному вопросу. В каких-то urls в вашем проекте. Вопросы, которые не относятся непосредственно к статье, задавайте, пожалуйста на...
АБ
21 марта 2019 г. 15:00
Артем Бел

а это где? сейчас ошибка в debag такая: Page not found (404)Request Method: GETRequest URL: http://amadowshop.site/accounts/profile/
21 марта 2019 г. 12:47
Евгений Легоцкой

не вижу здесь проблемы, поменяйте url для callback в приложения oauth в социальных сетях https://amadowshop.site/auth/verify/complete/facebook/
Сейчас обсуждают на форуме
U
25 марта 2019 г. 12:43
Unreal_man

Как сделать чтоб при клике на ячейку(ос андроид) ее сразу можно было редактировать?QGuiApplication::inputMethod()->show(); показывает клавиатуру, а вот что до этого прописать чтоб текст в ...
m
24 марта 2019 г. 10:36
monevich

Отвечу на свой же вопрос, может кому то это пригодится. Да, можно в функции main использовать такую конструкцию. При запуске программы из Qt передаю свой аргумент в параметрах командной строк...
22 марта 2019 г. 12:29
Дмитрий

Да, мьютекс добавил, но в том потоке, где сигнал вызывается.
ВН
22 марта 2019 г. 9:04
Волчонок Над-Пропастью

Да, на эту проблему! Зато у меня теперь новая, ругается на подключение QMediaPlayer, пишет, что не находит подобного файла или библиотеки. Пока не нашла как исправить, только вариант с переуст...
22 марта 2019 г. 8:58
Михаиллл

4) это , похоже, для создания видоизмененных страниц, для анимации. 3,5) добавить фвйл/qt/ui.qml
Присоединяйтесь к нам в социальных сетях

Для зарегистрированных пользователей на сайте присутствует минимальное количество рекламы