периодический вызов функции по таймеру в C++11
От: gencoder  
Дата: 10.01.17 12:36
Оценка:
Можно ли сделать в c++11 аналог Qt-класса, периодически запускающего некоторый метод класса или функцию action(),
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(action()));
timer->start(1000);

без использования библиотеки Qt и чтобы был кроссплатформенным?
chrono с++11
Re: периодический вызов функции по таймеру в C++11
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 10.01.17 12:47
Оценка:
Здравствуйте, gencoder, Вы писали:

g> Можно ли сделать в c++11 аналог Qt-класса, периодически запускающего некоторый метод класса или функцию action(),

g> без использования библиотеки Qt и чтобы был кроссплатформенным?

// CallbackTimer.h

#if !defined(__CallbackTimer_h)
#define __CallbackTimer_h

#include <functional>
#include <thread>
#include <atomic>

class CallbackTimer
{
public:
    CallbackTimer(void);
    ~CallbackTimer(void);

public:
    void startWorkerThread(int timeInterval, std::function<void(void)> callbackFunc);
    void stopWorkerThread(void);

private:
    std::thread m_workerThread;
    std::atomic<bool> m_continueWorkerThread;
};

inline CallbackTimer::CallbackTimer(void):
m_continueWorkerThread(false)
{
}

#endif   // __CallbackTimer_h


// CallbackTimer.cpp

#include <chrono>

#include "CallbackTimer.h"

CallbackTimer::~CallbackTimer(void)
{
    if (m_continueWorkerThread.load(std::memory_order_acquire))
    {
        stopWorkerThread();
    }
}

void CallbackTimer::startWorkerThread(int timeInterval, std::function<void(void)> callbackFunc)
{
    if (m_continueWorkerThread.load(std::memory_order_acquire))
    {
        stopWorkerThread();
    }

    m_continueWorkerThread.store(true, std::memory_order_release);

    m_workerThread = std::thread([this, timeInterval, callbackFunc](void)
    {
        while (m_continueWorkerThread.load(std::memory_order_acquire))
        {
            callbackFunc();
            std::this_thread::sleep_for(std::chrono::milliseconds(timeInterval));
        }
    });
}

void CallbackTimer::stopWorkerThread(void)
{
    m_continueWorkerThread.store(false, std::memory_order_release);
    if (m_workerThread.joinable())
    {
        m_workerThread.join();
    }
}
avalon/2.0.3
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: периодический вызов функции по таймеру в C++11
От: niXman Ниоткуда https://github.com/niXman
Дата: 10.01.17 13:26
Оценка:
Здравствуйте, gencoder, Вы писали:

G>Можно ли сделать в c++11 аналог Qt-класса, периодически запускающего некоторый метод класса или функцию action(),

G>
G>timer = new QTimer(this);
G>connect(timer, SIGNAL(timeout()), this, SLOT(action()));
G>timer->start(1000);
G>

G>без использования библиотеки Qt и чтобы был кроссплатформенным?

без использования дополнительного потока — вряд ли... хоть это и невероятно неэффективное решение.

и стОит помнить, что калбяк будет зваться из другого потока, а не как в Qt.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: периодический вызов функции по таймеру в C++11
От: so5team https://stiffstream.com
Дата: 10.01.17 13:29
Оценка:
Здравствуйте, gencoder, Вы писали:

G>Можно ли сделать в c++11 аналог Qt-класса, периодически запускающего некоторый метод класса или функцию action(),

G>
G>timer = new QTimer(this);
G>connect(timer, SIGNAL(timeout()), this, SLOT(action()));
G>timer->start(1000);
G>

G>без использования библиотеки Qt и чтобы был кроссплатформенным?

https://sourceforge.net/p/sobjectizer/wiki/timertt%201.1/

Можно использовать и в виде timer_thread (т.е. дополнительный поток, на котором будут запускаться события), так и в виде timer_manager (т.е. все операции выполняются на одном и том же потоке, но методы timer_manager-а нужно будет самостоятельно вручную вызывать).
Re[2]: периодический вызов функции по таймеру в C++11
От: Слава  
Дата: 10.01.17 13:37
Оценка:
Здравствуйте, niXman, Вы писали:

X>без использования дополнительного потока — вряд ли... хоть это и невероятно неэффективное решение.


Таймеров без использования дополнительного потока не бывает. Кто-то должен отсчитывать время и послать запрос, или поставить запрос в уже известную очередь, вроде виндового WM_TIMER. Или же нужна поддержка подобного от системы, в виде подобия прерываний, в линуксовом виде — сигналов. В яве используется именно поток и дерево ожиданий, а инженеров Sun, которые яву придумывали, нельзя назвать неграмотными.
Re: периодический вызов функции по таймеру в C++11
От: Sharpeye Россия  
Дата: 10.01.17 13:41
Оценка:
Здравствуйте, gencoder, Вы писали:

G>Можно ли сделать в c++11 аналог Qt-класса, периодически запускающего некоторый метод класса или функцию action(),

G>
G>timer = new QTimer(this);
G>connect(timer, SIGNAL(timeout()), this, SLOT(action()));
G>timer->start(1000);
G>

G>без использования библиотеки Qt и чтобы был кроссплатформенным?

Прямо влоб:

struct Timer
{
    std::future< void > start( std::chrono::milliseconds dt, std::function< void () > cb )
    {
        auto t = std::chrono::steady_clock::now() + dt;

        return std::async( std::launch::async, [=]
        {
            std::unique_lock< std::mutex > lock{ mtx };
            cv.wait_until( lock, t, []{ return false; } );

            cb();
        } );
    }

    std::mutex mtx;
    std::condition_variable cv;
};

void main()
{
    Timer timer;

    auto f = timer.start( std::chrono::milliseconds{ 1000 }, []{
        std::cout << "Timeout" << std::endl;
    } );

    f.get();
}
Re[2]: периодический вызов функции по таймеру в C++11
От: Sharpeye Россия  
Дата: 10.01.17 15:02
Оценка:
А проще вместо mtx и cv:
std::this_thread::sleep_until( t );
Re: периодический вызов функции по таймеру в C++11
От: SaZ  
Дата: 11.01.17 12:36
Оценка:
Здравствуйте, gencoder, Вы писали:

G>Можно ли сделать в c++11 аналог Qt-класса, периодически запускающего некоторый метод класса или функцию action(),

G>
G>timer = new QTimer(this);
G>connect(timer, SIGNAL(timeout()), this, SLOT(action()));
G>timer->start(1000);
G>

G>без использования библиотеки Qt и чтобы был кроссплатформенным?

Чтобы это заработало в Qt вам так же надо вызвать QEventLoop::exec или его статический аналог у QCoreApplication.
Таймеры в Qt работают благодаря очереди сообщений, в том числе при многопоточном использовании.

Т.е. вам нужно сделать на С++ аналог очереди сообщений и цикла обработки сообщений и где-то его гонять.

Я думаю, если вы более точно опишите, что именно вам нужно в конечном счёте, то вам посоветуют что-то более подходящее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.