C++ 非阻塞异步定时器

2024-03-15

我读过很多关于这个问题的帖子,但没有找到这个问题的答案。 我想制作一个在后台运行并在完成后执行某些操作的计时器类。甚至我想一次调用多个异步倒计时的计时器。

我在搜索这个类时发现了它,它似乎有效,但不在后台。我怎样才能将它转换为我想要的?

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

定时器.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! ----------------
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 非阻塞异步定时器 的相关文章

随机推荐

  • 如何检查 uint8_t 是否作为类型存在,而不是 unsigned char?

    我有两个编译器 一种可以识别 uint8 t GCC ARM EABI 另一种则不能 Renesas M16 标准工具链 Renesas 工具链不兼容 ANSI C 因此您可以丢弃 因此 uint8 t uint16 t 未定义为现有类型
  • 如何搜索 git 存储库历史记录以查找合并错误?

    在我们过去的某个时刻 git 的开发分支被合并了 然而 做出了错误的合并决定 因此一些代码没有进入我们预期的主分支 在最终合并到主分支之前 不同分支进行了多次合并 因此分支和合并历史相当复杂 有没有一种简单的方法来搜索 git 存储库以确定
  • 在 R 中创建默认评论标题模板?

    是否可以在 R 中为所有新脚本创建默认注释标题模板 我通常在所有脚本的顶部包含一些标准信息 并希望自动执行创建评论标题的过程 例如 Project Script purpose Date Author 按照上面 lmo 的建议 我通过编辑位
  • Pandas 滚动窗口 - datetime64[ns] 未实现

    我正在尝试使用 Python Pandas 构建一些图表 我有每秒采样的数据 这是一个示例 Index Time Value 31362 1975 05 07 07 59 18 36 151612 31363 1975 05 07 07 5
  • WEBHDFS REST API 将文件从 Windows 服务器/本地文件夹/桌面复制/移动到 HDFS

    使用 WEBHDFS REST API 调用 我可以将文件从 Windows 计算机 即 Windows 服务器或 Windows 本地文件夹或桌面 传输或复制到 Hadoop HDFS 文件系统吗 如果是 有任何示例命令信息吗 我已经尝试
  • 分解量子态

    我正在寻找采用由位组成的加权经典状态之和组成的任意量子态的算法 如下所示 0000 gt 2 0011 gt 2 0100 gt 2 0111 gt 2 并使用张量积将其分解为更紧凑的形式 如下所示 0 gt x 0 gt 1 gt x 0
  • 循环或重复一组任务直到成功

    我目前有一个包含任务文件的剧本 在该任务文件中 我想检查一个条件 如果该条件的退出代码不等于 0 则应重复任务文件中的所有步骤 我已经尝试了块和循环的一些变体 但我还没有找到一种方法来使它执行我上面描述的操作 目前我有这样的事情 tasks
  • eax如何存储大小大于4字节的返回值?

    EAX在32位平台上用于存储函数的返回值 我想知道如果函数的返回值的大小大于4个字节 eax如何处理 在这种情况下 操作系统可以将返回值保存在堆栈上 并将堆栈地址存储在EAX中 但是操作系统如何判断EAX中存储的值是返回值的地址还是实际上是
  • 单括号和双括号 Numpy 数组的区别?

    这两个 numpy 对象有什么区别 import numpy as np np array 0 0 0 0 np array 0 0 0 0 In 71 np array 0 0 0 0 shape Out 71 1 4 In 72 np
  • 在 [FINE UPLOADER] 中显示以前上传的图像

    我正在使用精细的上传器插件来上传图像 图片上传工作正常 我想做的是 当图像上传后刷新页面时 精细上传器应该显示以前上传的图像 这是我的代码 accordion on shown bs collapse function activeShop
  • 如何在 Laravel Eloquent 中使用带有子查询的内连接

    注意 这是 laravel 5 3 基本上 当用户选择阿拉伯语翻译时 我正在运行查询 完整的 sql 如下所示 select s ref t text as ref ar FROM stores AS s INNER JOIN SELECT
  • 在 SharePoint 2013 中以编程方式创建文件夹

    目前我有在中创建文件夹的代码Documents运行时目录 using var context new Microsoft SharePoint Client ClientContext sharePointSite context Cred
  • 方案中的河内塔(递归)

    今天在scheme中写了如下代码 但是求值错误 请不要告诉我我编程很糟糕 我知道这是一个经典的递归问题 但我遇到了麻烦 define towers of hanoi n source temp dest if n 1 begin displ
  • 解析 ISO 8601 值 24:00:00 的日期失败

    我正在尝试解析来自数据源的传入日期 无法更改 它给了我 ISO 8601 格式示例的时间 2007 04 05T24 00 然而在 Net 中它无法将其解析为有效时间 维基百科指出它应该是有效的格式 维基百科 ISO 8601 http e
  • 更少的 mixin 和变量

    我有以下混合 iconFont color green font size 18px color color font size font size 如果我只想更改第二个变量值 我需要编写第一个变量默认值吗 h1 iconFont gree
  • Drupal 7在自定义主题中覆盖jquery js文件

    是否可以重写 覆盖自定义模板脚本变量中使用的默认 Drupal 7 26 jquery 我的意思是js文件之一 通过自定义主题来的一个 我试过这个sites all MYTPL template php但它不起作用 scripts misc
  • 不在映射中的字段包含在 ElasticSearch 返回的搜索结果中

    我想使用 Tire gem 作为 ElasticSearch 的客户端来索引 pdf 附件 在我的映射中 我从 source 中排除附件字段 以便附件不会存储在索引中 并且未在搜索结果中返回 mapping source gt exclud
  • Visual Studio Android 模拟器网络不工作

    I started using xamarin in visual studio and I installed visual studio android emulator Emulator works flawlessly but ne
  • 编辑超链接 Excel 2010 宏

    好的 我想创建一个宏来替换超链接的一部分 我的 Excel 文件中有大量的超链接 有没有办法创建一个宏来做到这一点 例如 www OldName com www Oldname com a www Oldname com b to www
  • C++ 非阻塞异步定时器

    我读过很多关于这个问题的帖子 但没有找到这个问题的答案 我想制作一个在后台运行并在完成后执行某些操作的计时器类 甚至我想一次调用多个异步倒计时的计时器 我在搜索这个类时发现了它 它似乎有效 但不在后台 我怎样才能将它转换为我想要的 Time