问题
I have what I thought was a simple pattern - I want to make a timepoint 5 seconds in the future, run a task which might take a while, and then sleep until that timepoint (potentially not sleeping at all if that time has already been reached.) However, whenever trying to use std::this_thread::sleep_until
with a timepoint in the past, my application instead hangs forever. Here is an MCVE:
#include <chrono>
#include <thread>
int main(){
std::this_thread::sleep_until(std::chrono::steady_clock::now() - std::chrono::seconds(1));
}
Using g++ (GCC) 4.8.5, this never returns. I've also tried system_clock with the same results. Using strace to examine what's happening, the last thing I get is:
nanosleep({4294967295, 0},
so I guess it would return eventually, but I don't feel like waiting that long.
Is this a g++ bug? I can't imagine this behavior is intentional. I found the question Is behaviour well-defined when sleep_until() specifies a time point in the past? but it doesn't seem that any conclusion was actually reached on whether or not the standard actually specifies what should happen. I've since implemented another solution to my problem; I'm just curious as to whether or not what I'm seeing is UB or a bug.
回答1:
Looks like a bug:
30.2.4 Timing specifications [thread.req.timing]
4 The functions whose names end in
_until
take an argument that specifies a time point. These functions produce absolute timeouts. Implementations should use the clock specified in the time point to measure time for these functions. Given a clock time point argument Ct, the clock time point of the return from timeout should be Ct+Di+Dm when the clock is not adjusted during the timeout. (...)
Where Di is defined as a "quality of implementation" delay, and Dm is defined as a "quality of management" delay.
As Howard Hinnant brilliantly emphasizes, an implementation should strive to minimize Di and Dm:
30.2.4 Timing specifications [thread.req.timing]
2 Implementations necessarily have some delay in returning from a timeout. Any overhead in interrupt response, function return, and scheduling induces a “quality of implementation” delay, expressed as duration Di. Ideally, this delay would be zero. Further, any contention for processor and memory resources induces a “quality of management” delay, expressed as duration Dm. The delay durations may vary from timeout to timeout, but in all cases shorter is better.
Note that this must be true no matter what the value of Ct is, and that an infinite delay is definitely not minimal.
As a small update, this is now fixed, as of version 4.9.3. Here is the information on the bug tracker.
来源:https://stackoverflow.com/questions/51755266/sleep-until-a-timepoint-in-the-past