tags:

views:

190

answers:

3

For example, if I do time.sleep(100) and immediately hibernate my computer for 99 seconds, will the next statement be executed in 1 second or 100 seconds after waking up?

If the answer is 1 second, how do you "sleep" 100 seconds, regardless of the length of hibernate/standby?

+2  A: 

Clearly, you must sleep according to real, elapsed time.

The alternative (sleeping according to some other clock that "somehow" started and stopped) would be unmanageable. How would your application (which is sleeping) be notified of all this starting and stopping activity? Right, it would have to be woken up to be told that it was not supposed to run because the system was hibernating.

Or, perhaps, some super-sophisticated OS-level scheduler could be used to determine if some time the system was "busy" vs. "hibernating" counted against the schedules of various sleeping processes.

All too complex.

Indeed, if you check carefully, sleep is pretty approximate and any Unix Signal will interrupt it. So it's possible to wake early for lots of reasons. Control-C being the big example.

S.Lott
+5  A: 

time.sleep(N) attempts to sleep at least N seconds of elapsed, AKA "wall-clock" time - of course there can be no guarantee that the sleep will last exactly N seconds; for example, the thread becomes ready to execute again at that time, but it cannot necessarily preempt whatever other thread is executing at that time -- that's the operating system's decision to make, not any programming language's; on the other hand, sleep may be prematurely interrupted by various kinds of events (such as interrupts).

If you can find on your operating system some clock-like thingy that only advances when the system's state is the one you care about (e.g. "not hybernated", in your case), then of course you can go back to sleep if you wake up again "too early".

For example, on Windows 7, QueryUnbiasedInterruptTime is specifically documented to "not include time the system spends in sleep or hibernation" and to use units of 100 nanoseconds. So if you call that, e.g. through ctypes, you can achieve the effect you want:

def unbiasedsleep(n):
  start = kernel32.QueryUnbiasedInterruptTime()
  target = start + n * 10 * 1000 * 1000
  while True:
    timeleft = target - kernel32.QueryUnbiasedInterruptTime()
    if timeleft > 0:
      time.sleep(timeleft / (10 * 1000 * 1000.0))

I don't know how to get the equivalent of QueryUnbiasedInterruptTime on other releases of Windows or other operating systems, but then, you don't tell us what operating system(s) you're interested in, so it would be pretty pointless anyway to present a long laundry lists of approaches which may work similarly in different environments.

Alex Martelli
+2  A: 

I don't know exactly what you are trying to achieve, but

for i in range(100):sleep(1)

might work, as the hibernate would only use up to 1 seconds worth of the sleep

gnibbler