您可以实现没有“睡眠”状态的计时器吗?只能使用标准c ++ / c ++ 11吗? [英] Can you implement a timer without a "sleep" in it using standard c++/c++11 only?

查看:79
本文介绍了您可以实现没有“睡眠”状态的计时器吗?只能使用标准c ++ / c ++ 11吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

重要更新

注意:由于此问题专门与计时器有关,因此请务必注意,如果您使用的是std,则gcc中存在一个错误: :condition_variable :: wait_for(或wait_util),即使您传递了std :: chrono :: steady_clock时间点,它也会使用系统时钟。这意味着计时器不是单调的-即如果您将系统时间向前更改一天,则您的计时器可能不会在一天内触发+超时-如果您向后更改时间,则计时器可能会立即触发。

Note: since this question is specifically about timers, its important to note there is a bug in gcc that if you are using std::condition_variable::wait_for (or wait_util) it uses the system clock even if you pass it a std::chrono::steady_clock time point. This means the timer is not monotonic - i.e. if you change the system time forward by a day then your timer may not trigger for a day + your timeout - if you change the time backwards your timer may trigger immediately.

请参阅:使用wait_until的condition_variable解决方法系统时间更改

此错误的修复程序已进入gcc v10 +

The fix for this bug went into gcc v10+

END

我有以下代码(手工复制):

I have the following code (hand-copied in):

// Simple stop watch class basically takes "now" as the start time and 
// returns the diff when asked for.
class stop_watch {...}

// global var
std::thread timer_thread;

void start_timer(int timeout_ms)
{
    timer_thread = std::thread([timeout_ms, this](){
        stop_watch sw;
        while (sw.get_elapsed_time() < timeout_ms)
        {
            // Here is the sleep to stop from hammering a CPU
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }

        // Do timeout things here...
        std::cout << "timed out!" << std::endl;
    })
}

我不想陷入困境在我编写的课程的详细信息中,这是一个非常精简的版本。完整的类调用函数回调,并具有取消计时器等的变量。

I did not want to get too bogged down in the detail of the class I writing so this is a very cut-down version. The full class calls a function call-back and has a variable to cancel the timer etc...

我只想着眼于睡眠状态。部分。我可以不睡觉而实施这样的事情吗,或者有更好的方法吗? -还是睡得很好? -我认为睡眠通常是不良设计的标志(我读过一些地方)...但是我想不出没有一个计时器来实现计时器的方法:(

I just wanted to focus on the "sleep" part. Can I implement something like this without a sleep or is there a better way to do it? - or is sleep perfectly good? - I was of the opinion that sleeps are generally a sign of bad design (I have read that a few places)... but I can't think of a way to implement a timer without one :(

其他说明:计时器应该具有可以随时停止/唤醒的要求,只是为了清楚起见添加了它,因为它似乎会影响采用哪种解决方案。在我的原始代码(不是此代码段)中,我使用了一个可以脱离循环的原子bool标志。

Additional Note: The timer should have the requirement to be able to be stopped/woken at any time. Just adding that for clarity because it appears to affect what kind of solution to go for. In my original code (not this snippet) I used an atomic bool flag that can break out of the loop.

推荐答案

C ++ 11为我们提供了 std :: condition_variable 。在您的计时器中,您可以等待直到满足条件:

C++11 provides us with std::condition_variable. In your timer you can wait until your condition has been met:

// Somewhere else, e.g. in a header:
std::mutex mutex;
bool condition_to_be_met{false};
std::condition_variable cv;

// In your timer:
// ...
std::unique_lock<std::mutex> lock{mutex};
if(!cv.wait_for(lock, std::chrono::milliseconds{timeout_ms}, [this]{return condition_to_be_met;}))
std::cout << "timed out!" << std::endl;

您可以在此处找到更多信息: https://en.cppreference.com/w/cpp/thread/condition_variable

You can find more information here: https://en.cppreference.com/w/cpp/thread/condition_variable

要表明已满足条件,请在另一个线程中执行此操作:

To signal that the condition has been met do this in another thread:

{
    std::lock_guard<std::mutex> lock{mutex}; // Same instance as above!
    condition_to_be_met = true;
}
cv.notify_one();

这篇关于您可以实现没有“睡眠”状态的计时器吗?只能使用标准c ++ / c ++ 11吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆