C 非阻滞异步计时器

C++ Non-blocking async timer

本文关键字:异步 计时器      更新时间:2023-10-16

我已经阅读了许多有关此问题的文章,但没有找到这个问题的答案。我想做一个在后台工作的计时器课程,完成工作后。甚至我想一次调用多个计时器,这些计时器不同步。

我在搜索它时找到了这堂课,这似乎在起作用,但在后台不行。我如何将其转换为我想做的事?

timer.h:

#ifndef TIMER_H
#define TIMER_H
#include <thread>
#include <chrono>
class Timer
{
public:
    typedef std::chrono::milliseconds Interval;
    typedef std::function<void(void)> Timeout;
    Timer(const Timeout &timeout);
    Timer(const Timeout &timeout,
          const Interval &interval,
          bool singleShot = true);
    void start(bool multiThread = false);
    void stop();
    bool running() const;
    void setSingleShot(bool singleShot);
    bool isSingleShot() const;
    void setInterval(const Interval &interval);
    const Interval &interval() const;
    void setTimeout(const Timeout &timeout);
    const Timeout &timeout() const;
private:
    std::thread _thread;
    bool _running = false;
    bool _isSingleShot = true;
    Interval _interval = Interval(0);
    Timeout _timeout = nullptr;
    void _temporize();
    void _sleepThenTimeout();
};
#endif // TIMER_H
enter code here

timer.cpp:

#include "Timer.h"
Timer::Timer(const Timeout &timeout)
    : _timeout(timeout)
{
}
Timer::Timer(const Timer::Timeout &timeout,
             const Timer::Interval &interval,
             bool singleShot)
    : _isSingleShot(singleShot),
      _interval(interval),
      _timeout(timeout)
{
}
void Timer::start(bool multiThread)
{
    if (this->running() == true)
        return;
    _running = true;
    if (multiThread == true) {
        _thread = std::thread(
                    &Timer::_temporize, this);
    }
    else{
        this->_temporize();
    }
}
void Timer::stop()
{
    _running = false;
    _thread.join();
}
bool Timer::running() const
{
    return _running;
}
void Timer::setSingleShot(bool singleShot)
{
    if (this->running() == true)
       return;
    _isSingleShot = singleShot;
}
bool Timer::isSingleShot() const
{
    return _isSingleShot;
}
void Timer::setInterval(const Timer::Interval &interval)
{
    if (this->running() == true)
       return;
    _interval = interval;
}
const Timer::Interval &Timer::interval() const
{
    return _interval;
}
void Timer::setTimeout(const Timeout &timeout)
{
    if (this->running() == true)
       return;
    _timeout = timeout;
}
const Timer::Timeout &Timer::timeout() const
{
    return _timeout;
}
void Timer::_temporize()
{
    if (_isSingleShot == true) {
        this->_sleepThenTimeout();
    }
    else {
        while (this->running() == true) {
            this->_sleepThenTimeout();
        }
    }
}
void Timer::_sleepThenTimeout()
{
    std::this_thread::sleep_for(_interval);
    if (this->running() == true)
        this->timeout()();
}

以下类需要一个时间来计算的参数,并在末尾执行函数:

#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
class Timer {
public:
    Timer(size_t time, const std::function<void(void)>& f) : time{std::chrono::milliseconds{time}}, f{f} {}
    ~Timer() { wait_thread.join(); }
private:
    void wait_then_call()
    {
        std::unique_lock<std::mutex> lck{mtx};
        for(int i{10}; i > 0; --i) {
            std::cout << "Thread " << wait_thread.get_id() << " countdown at: " << 't' << i << 'n';
            cv.wait_for(lck, time / 10);
        }
        f();
    }
    std::mutex mtx;
    std::condition_variable cv{};
    std::chrono::milliseconds time;
    std::function <void(void)> f;
    std::thread wait_thread{[this]() {wait_then_call(); }};
};
int main()
{
    auto f = []() {std::cout << "---------------- I waited to print! ----------------n"; };
    Timer t1{3000,f};
    Timer t2{10'000,f};
    Timer t3{20'000,f};
    Timer t4{1000,f};
}

生产:

Thread Thread 43184 countdown at:       Thread 24004 countdown at:      10
Thread 61592 countdown at:      10
72408 countdown at:     10
10
Thread 24004 countdown at:      9
Thread 24004 countdown at:      8
Thread 72408 countdown at:      Thread 24004 countdown at:      9
7
Thread 24004 countdown at:      6
Thread 24004 countdown at:      5
Thread 72408 countdown at:      8
Thread 24004 countdown at:      4
Thread 24004 countdown at:      3
Thread 24004 countdown at:      2
Thread 72408 countdown at:      7
Thread 24004 countdown at:      1
Thread 61592 countdown at:      9
---------------- I waited to print! ----------------
Thread 72408 countdown at:      6
Thread 72408 countdown at:      5
Thread 72408 countdown at:      4
Thread 43184 countdown at:      9
Thread 61592 countdown at:      8
Thread 72408 countdown at:      3
Thread 72408 countdown at:      2
Thread 72408 countdown at:      1
Thread 61592 countdown at:      7
---------------- I waited to print! ----------------
Thread 43184 countdown at:      8
Thread 61592 countdown at:      6
Thread 61592 countdown at:      5
Thread 43184 countdown at:      7
Thread 61592 countdown at:      4
Thread 61592 countdown at:      3
Thread 43184 countdown at:      6
Thread 61592 countdown at:      2
Thread 61592 countdown at:      1
Thread 43184 countdown at:      5
---------------- I waited to print! ----------------
Thread 43184 countdown at:      4
Thread 43184 countdown at:      3
Thread 43184 countdown at:      2
Thread 43184 countdown at:      1
---------------- I waited to print! ----------------