我有以下代码(手工复制):
// 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;
})
}
Run Code Online (Sandbox Code Playgroud)
我不想太沉迷于我写的课程的细节,所以这是一个非常简化的版本.完整的类调用函数回调并具有取消计时器等的变量...
我只想专注于"睡眠"部分.我可以在没有睡眠的情况下实现这样的事情,还是有更好的方法来实现它? - 还是睡得很好? - 我认为睡眠通常是糟糕设计的标志(我已经读过几个地方)......但我想不出一种方法来实现没有一个计时器:(
附加说明:计时器应该能够随时停止/唤醒.只是为了清晰起见而添加它,因为它似乎影响了要采用的解决方案.在我的原始代码(不是这个代码片段)中,我使用了一个可以突破循环的原子bool标志.
Seb*_*ian 34
C++ 11为我们提供了std::condition_variable.在您的计时器中,您可以等到满足您的条件:
// 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;
Run Code Online (Sandbox Code Playgroud)
您可以在此处找到更多信息:https://en.cppreference.com/w/cpp/thread/condition_variable
要表明已满足条件,请在另一个线程中执行此操作:
{
std::lock_guard<std::mutex> lock{mutex}; // Same instance as above!
condition_to_be_met = true;
}
cv.notify_one();
Run Code Online (Sandbox Code Playgroud)
虽然您的代码将"正常工作",但它对于作为计时器的预期目的而言是次优的.
存在std::this_thread::sleep_until,这取决于实现,可能只是刚刚呼吁sleep_for反正做一些数学后,但可能会使用适当的计时器,这是在精度和可靠性方面大大优于.
一般来说,睡觉并不是最好,最可靠,最准确的事情,但有时候,如果只是等待一段大概的时间就是预期的,它可以"足够好".
在任何情况下,如你的例子中反复睡眠少量是一个坏主意.这将在不必要的重新安排和唤醒线程上烧掉大量CPU,并且在某些系统上(特别是Windows,尽管Windows 10在这方面不再那么糟糕),它可能会增加相当多的抖动和不确定性.需要注意的是不同的Windows版本一轮调度的粒度不同,所以除了一般是不是过于精确,你甚至没有一致的行为.舍入几乎是"谁关心"单个大等待,但对于一系列小等待来说这是一个严重的问题.
除非过早地中止计时器的能力是必要的(但在这种情况下,还有更好的方法来实现它!),你应该在整个持续时间内完全睡一次,而不是更多.为了正确,你应该检查你确实得到了你预期的时间,因为有些系统(特别是POSIX)可能会睡眠不足.
过度睡眠是一个不同的问题,如果你需要它的权利,因为即使你检查并正确地检测这种情况下,一旦发生有什么可以做这件事(的时间已经过去了,一去不复返).但唉,这只是睡眠的根本弱点,你可以做的不多.幸运的是,大多数人可以在大多数情况下解决这个问题.
| 归档时间: |
|
| 查看次数: |
4155 次 |
| 最近记录: |