C++ 非阻塞异步定时器

标签 c++ multithreading timer background

我看了很多关于这个的帖子,但没有找到这个问题的答案。 我想制作一个计时器类,它在后台工作,完成后做一些事情。甚至我想一次调用多个异步倒计时的计时器。

我在搜索它时发现了这个类,它似乎有效,但在后台不起作用。我如何才能将其转换为执行我想要的操作?

定时器.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

定时器.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! ----------------

关于C++ 非阻塞异步定时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41152393/

相关文章:

c++ - 至少在 Visual Studio 中,c++11 下 fmod(和其他)的不同行为

c++ - 在类中使用静态互斥锁

c# - 如何在处理经过的事件时阻止计时器?

c# - wpf Storyboard死亡

c++ - SDL 2 通过 SpriteManager 在屏幕上显示图像,获取指针中断

c++ - Lambda 隐式捕获因从结构化绑定(bind)声明的变量而失败

c++ - 将 C++ 编译器添加到 Eclipse C 项目

multithreading - Postgresql parallel bulk INSERT with worker 不并行化

c++ - 两个具有共享缓冲区的等待线程(生产者/消费者)

c - 对C的定时器有一些困惑