0

考虑下面的循环。这是我试图解决的问题的简化示例。我想限制每秒调用doSomething函数的次数。由于循环工作得非常快,我想我可以使用速率限制器。假设我通过使用不同的x数字运行它找到了一个合适的值。

unsigned int incrementionRate = x;
unsigned int counter == 0;

while (true) {

    double seconds = getElapsedSeconds();
    print(seconds);

    counter = (counter + 1) % incrementionRate;
    if (counter == 0) {
        doSomething();
    }
}

我想知道如果我在较低的时钟频率下工作,对doSomething函数的调用次数是否会更少。在这种情况下,我想将对doSomething函数的调用次数限制为每秒一次。我写的第二个循环如下。

float epsilon = 0.0001;
while (true) {

    double seconds = getElapsedSeconds();
    print(seconds);

    if (abs(seconds - floor(seconds)) <= epsilon) {
        doSomething();
    }
}

这会对不同的时钟周期起到作用还是仍然存在问题?另外,我想知道是否有更好的方法来做到这一点。我以前从未使用过时钟频率,并试图了解在使用有限资源时关注点有何不同。

注意:使用睡眠不是一种选择。

4

3 回答 3

4

如果我能很好地理解这个问题,你可以使用std::chrono::steady_clock你只需在每经过一秒时添加一秒的方法。

例子:

#include <chrono>

auto end_time = std::chrono::steady_clock::now();

while (true) {
    // only call doSomething once a second
    if(end_time < std::chrono::steady_clock::now()) {
        doSomething();
        // set a new end time a second after the previous one
        end_time += std::chrono::seconds(1);
    }

    // do something else
}

于 2021-06-06T20:31:06.040 回答
2

如果您真的在循环中做其他事情,Ted回答很好;但是,如果不是,这会导致忙碌的等待,这只会白白消耗您的 CPU。

在这种情况下,您应该宁愿让您的线程休眠:

    std::chrono::milliseconds offset(200);
    auto next = std::chrono::steady_clock::now();
    for(;;)
    {
        doSomething();
        next += offset;
        std::this_thread::sleep_until(next);
    }

您需要包含chronothread标题。

于 2021-06-06T20:41:43.113 回答
0

最后我决定采用一种更简单的方法。使用可调整的时间间隔,只存储最新的更新时间,没有引入任何新机制。老实说,现在我不知道为什么我一开始想不到。过度思考是个问题。:)

double lastUpdateTimestamp = 0;
const double updateInterval = 1.0;

while (true) {

    double seconds = getElapsedSeconds();
    print(seconds);

    if ((elapsedSeconds - lastUpdateTimestamp) >= updateInterval) {
        doSomething();
        lastUpdateTimestamp = elapsedSeconds;
    }
}
于 2021-06-09T11:37:22.727 回答