您可以实现没有“睡眠”状态的计时器吗?只能使用标准c ++ / c ++ 11吗? [英] Can you implement a timer without a "sleep" in it using standard c++/c++11 only?
问题描述
重要更新
注意:由于此问题专门与计时器有关,因此请务必注意,如果您使用的是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屋!