【问题标题】:Chrono timer in C++ to doubleC ++中的计时计时器加倍
【发布时间】:2020-03-01 16:45:57
【问题描述】:

我怎样才能创建一个计时器,在一定的持续时间后,它会做一些事情?到目前为止,我一直在尝试使用 % 操作。我在函数开始时做了一个计时器,然后减去当前时间(now() 函数)然后 i % 差 5 因为我想要 5 秒过去:

(at the start of the program i defined start as high_resolution_clock::now())
duration<double> dur = start-high_resolution_clock::now();
if(dur%5==0)

我得到的错误是:没有运算符“==”与这些操作数匹配——操作数类型是:std::chrono::duration> == int

【问题讨论】:

  • duration 有一个成员 count() 来返回毫秒数。见这里:stackoverflow.com/questions/20785687/…,或者尝试一个简单的网络搜索“Chrono to int”——这就是我所做的......
  • %(模运算符)只能用于整数。您可以尝试使用“long long int”类型(int64_t 或 uint64_t)。使用这个 int 你得到一个 64 位的整数,并且模运算符可以正常工作。
  • 您遇到的第一个错误是什么?我收到有关 operator== 的错误,但这不是第一个错误。
  • 我建议你在一个单独的线程上运行它,在那里有一个循环运行你想每 5 秒运行一次的代码 - 运行后五秒休眠。

标签: c++ chrono


【解决方案1】:

你正在寻找类似的东西:

#include <chrono>

int main() {
    using namespace std::chrono_literals;
    using std::chrono::high_resolution_clock;
    auto start = high_resolution_clock::now();
    bool condition = true;
    while (condition) {
        auto time_passed = high_resolution_clock::now() - start;
        if( time_passed % 5s == 0s ) {
            // do your thing every 5 seconds
        }
        // ...
    }
}

Code version 1, Code version 2


说明

模数

modulo operation for duration 调用:duration % x 期望 x 是两者之一:

  • 另一个持续时间,在这种情况下,chrono 为您完成了获得durationx 的常见类型的工作,这将允许模.

  • 一些任意类型,在这种情况下duration 的内部类型应该能够与x 进行模运算。对于基于&lt;double&gt;duration,情况并非如此。

要允许对基于&lt;double&gt;duration 进行取模,需要使用duration_cast 或使用上面的第一个取模选项,以及另一个duration

比较

模运算返回duration,如参考中所示。要将其与int(即0)进行比较,需要将其转换为int(因为durationint 不可比较),这可以通过调用计数来完成,例如:

if ( (time_passed % 5s).count() == 0 )

或者,我们可以像上面那样将其与实际持续时间进行比较。


重要的设计说明

即使上面的代码有效,当我们达到精确的模数时,我们会做这件事,duration 计数的值不是以秒为单位的,所以如果我们错过了 5 秒 2 纳秒,我们将错过模数检查并且不会做我们的事情,那么我们将等待下一轮并且很可能会再次错过它。模数对于试图捕捉时间是一个非常糟糕的选择,因为我们采样的时间会跳跃。更好的方法是计算自从我们最后一次将事情作为触发器以来已经有 5 秒或更长时间。可以通过以下代码实现:

int main() {
    using namespace std::chrono_literals;
    using std::chrono::high_resolution_clock;
    auto start = high_resolution_clock::now();
    auto last_time_we_did_the_thing = start;
    bool condition = true;
    while (condition) {
        auto curr_time = high_resolution_clock::now();
        auto time_since_last_do_the_thing
           = curr_time - last_time_we_did_the_thing;
        if( time_since_last_do_the_thing >= 5s ) {
            // do your thing every 5 seconds
            last_time_we_did_the_thing = curr_time;
        }
        // ...
    }
}

Code ^

【讨论】:

  • 如果你解释一下为什么,这个答案会更好。
  • @AsteroidsWithWings 会尝试。现在 Howard Hinnant 出现在页面上让我有点冷 :-) 至少如果我错了,我会有人看管。
  • 你做得很好。 :-) 但是你可以在不使用.count()的情况下重写它吗?
  • 好多了!顺便说一句,那是我的赞成票。现在你只需要稍微清理一下你的解释。 :-)
  • @HowardHinnant 完成了!与 Howard Hinnant 在 std::chrono 上的私人教程,+upvote 奖金 :-) 多么荣幸和高兴!
猜你喜欢
  • 1970-01-01
  • 2019-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多