7

In *nix python signaling allows me to stop sleep before it is ready. Is there any similar mechanism available in windows -- seems that all the methods end up intercepting code only after the sleep?

Code example:

from time import sleep
.. do something that will intercept the sleep
try:
    sleep(60)
finally:
    print 'how to get here under 60 seconds in windows?'

Similar question that doesn't have an answer for windows: break/interrupt a time.sleep() in python

Community
  • 1
  • 1
mkorpela
  • 4,317
  • 2
  • 19
  • 21
  • 5
    Can you write your code so it's waiting on a `threading.Event`, with a timeout of 60s, and hit that event from another thread if you want to cancel the wait? – Thomas K Dec 08 '11 at 12:54
  • 1
    first read the sentence parsing classic punctuation. Wish there was a way to stop time by sleeping somewhere. – Simon Bergot Dec 08 '11 at 14:12
  • It is not my code. It is unkown client code that I am trying to stop after timeout has occurred. It seems that in cpython no really good mechanism exists.. and yeah we have also tried threads and subprocess is a no go. – mkorpela Dec 08 '11 at 14:34

2 Answers2

5

The Python documentation for signal says:

• Although Python signal handlers are called asynchronously as far as the Python user is concerned, they can only occur between the “atomic” instructions of the Python interpreter. This means that signals arriving during long calculations implemented purely in C (such as regular expression matches on large bodies of text) may be delayed for an arbitrary amount of time.

whereas time says:

The actual suspension time may be less than that requested because any caught signal will terminate the sleep() following execution of that signal’s catching routine.

On Windows, apparently time.sleep() is not implemented in accordance with the documentation, because the handler for a signal received during sleep is not acted upon until the full duration of the sleep is finished. The following example:

import signal, time

def handler(signum, frame):
    print('Signal handler called with signal', signum)

signal.signal(signal.SIGINT, handler)

print("signal set, sleeping")
time.sleep(10)
print("sleep done")

prints:

signal set, sleeping
Signal handler called with signal 2
sleep done

with the first line occurring immediately and the second two after 10 seconds, regardless of when the interrupt occurs.

As Thomas K suggests, a better strategy would be to use threads and synchronization.

Dave
  • 3,834
  • 2
  • 29
  • 44
1

I'm not sure if this will do it for you, but here's a little workaround you could do:

for i in range(60):
    if checkIfIShouldInterruptSleep():
         break
    time.sleep(1)
print "Finished Sleeping!"

It's only accurate to the second, but it might serve your purpose. Happy coding!

Cosine
  • 572
  • 4
  • 18