time.monotonic() roll over

Dave Angel davea at davea.name
Fri Dec 5 00:29:44 EST 2014


On 12/04/2014 09:54 PM, Steven D'Aprano wrote:
> Dave Angel wrote:
>
>> On 12/04/2014 07:39 PM, Steven D'Aprano wrote:
>>> Marko Rauhamaa wrote:
>>>
>>>> So, if I call
>>>>
>>>> time.sleep(86400)
>>>>
>>>> and the program is suspended for 24 hours, should time.sleep() return
>>>> right after it is resumed or after another 24 hours?
>>>
>>> If the program is suspended, then no time should pass for that program.
>>> Since sleep() is given in terms of a duration, not an absolute time
>>> ("sleep until now + 24 hours"), if no time passes for that program,
>>> sleep() should sleep for 24 hours *after the program resumes*.
>>>
>>> Unfortunately a lot of systems get that wrong. E.g. I just ran "sleep 30"
>>> from my Linux shell, immediately paused it using Ctrl-Z, waited a couple
>>> of minutes, and used fg to continue. It returned immediately.
>>>
>>> Why is this behaviour wrong?
>>>
>>> Consider why people might call sleep. They're normally calling it to wait
>>> for something else to complete. Often that something else is an external
>>> process ("wait a few seconds to let the hard drive finish syncing, wait
>>> for the web server to get less busy, wait for the user to catch up...")
>>> but it might be another thread in the same process. If the process is
>>> suspended, that other thread won't get to run, and so even though time on
>>> the outside has continued to move forward, from the perspective of the
>>> process, it hasn't.
>>>
>>> The same applies even more so if the process is running in a virtual
>>> machine which has just been suspended.
>>>
>>> The same applies if the system clock is adjusted mid-sleep. If I call
>>> sleep 60, then immediately adjust the clock forward an hour (say, due to
>>> a daylight savings adjustment), that shouldn't cause sleep to return. It
>>> should still suspend for 60 seconds.
>>
>> And I say you have it exactly backwards.  People should NOT call sleep()
>> to measure something,
>
> I never suggested you call sleep to measure something. You call sleep to
> *wait* for something. I even used the word "wait" four times in the above.

I mentioned measurement because I couldn't imagine any other reason you 
would be arguing the other side.  You're certainly not waiting for the 
event, wleep has no parameters that let you specify what event you might 
be waiting for.


>
>> they should only call it to release the processor
>> for "up to" a specified time.
>
> That's silly. Zero is "up to" any positive value you want. Do you really
> intend to say that this would be an acceptable implementation of sleep()?
>
> def sleep(delay):
>      return
>

Yes, of course.  Not very machine efficient, but perfectly correct. 
Because the testing code will make its check, and turn right around and 
issue another sleep call.  This is called a busy loop, and I mention it 
below.  It is the degenerate (if inefficient) form.


>
>> That time should normally be a major
>> fraction of the time that some external event is expected to take.  Then
>> the code should check the external event and sleep some more if necessary.
>>
>> If efficiency were not an issue, the code would just do a busy loop,
>> checking the external condition repeatedly.
>
> In many cases, you don't have an external condition that can be easily or
> practically checked. So you estimate how long you need to wait, add a
> safety margin, and write "sleep 5" (for some value of 5), and hope.
>
> If you are a sys admin writing a script that runs during boot time, you do
> that a lot. Or at least the ones I work with do :-)
>
>
>> Since the OS has no way of knowing whether the thing being waited for is
>> a thread, another process, a human being, a network operation, or the
>> end of the world, the interpretation of sleep needs to be the most
>> conservative one.
>
> I agree! And returning immediately is not the most conservative one.
>
> The most conservative approach is to assume that while you're suspended,
> *everything else* is suspended too, so when you resume you still have to
> sleep for the full N seconds.
>
>
>> There are many ways of suspending a process, and some
>> of them will also suspend the external event.  Since the OS cannot know
>> which case is significant, it has to return control to the caller at the
>> soonest of the many possible interpretations.
>
> /s/latest/
>

I guess we'll just have to agree to disagree.  I can now see the 
usefulness of a function like you describe, I just can't imagine it 
being the sleep() we've all come to know and love.


-- 
DaveA



More information about the Python-list mailing list