Vacassal Alsk
Vacassal Alsk

Reputation: 513

How can I make python sleep in real time?

I have code that looks like:

while True:
    do things over the internet:
    time.sleep(3600)

I would like time.sleep() to run even if my computer is asleep or I'm not logged on. For example, if I start the program, wait half an hour, log off (or put the machine to sleep), and come back an hour later, I would like it to have run again and be half an hour into the next cycle of waiting.

Upvotes: 0

Views: 942

Answers (2)

Dalen
Dalen

Reputation: 4236

You should see, but it is possible that time.sleep() breaks when your machine goes to sleep.

It breaks when some other stuff happens, like KeyboardInterrupt.

So, put sleep() into try statement, and use time.clock() or time.time() to see how much time has passed between sleep() interruption and next occurence of loop continuation to continue sleeping, or just leave it interrupted with:

try: time.sleep(360)
except: pass

So, the program should continue on without any errors.

But, if it is not as easy as that, you will have to use signals and/or service management to have OS notify your process that it should continue running or start the sleeping procedure (sleeping in sense of log off, not actual sleep of a loop).

See, when OS wants to log off or shut down, or go to sleep, it will send notification in form of some event, signal or service pause. Sleep, is somewhat specific, and it may not be so on all OSes.

You have to catch this and do something useful with it.

Signals you manage through signal module,

events are system specific, and it may be complicated. on Mac OS X it can be anything from high level event on AppScript or event queue, or MacPort message which complicates things, but APIs are out there, no worries.

On Windows you will probably have to use win32types winservice module to create useful service management.

Note that when OS goes for shut down or log off, it sends signals to processes. If process doesn't respond and quit, it usually asks user if it should quit it, or just kills the process.

So, you have to register your process accordingly that it doesn't terminate, i.e. it has to be a service or daemon.

To solve problems of returning from sleep mode, it would be better to use threading.Timer() to do your job.

It is a thread that will call the function you register after specified time.

You change it's mode to daemon before starting it, and leave the main loop to catch events or signals or whatever.

When the time passes your function will be run. Then you can notify main loop to stop other processing and do your job.

If a loop detects return from sleep or logging in, it can call your function directly and restart the timer.

When you get hang of it all, it is easy, don't worry. Just a lot to read. :D

There might be a lot of other solutions.

Like auto starting some little process upon logging in that says to your process that it should do something etc. etc. Now all depends on your creativity.

Upvotes: 1

Delioth
Delioth

Reputation: 1554

You can have it save the time and check against that every minute or so, e.g. (pseudocode)

lastDone = None  # Avoid unbound local errors
while True:
    if lastDone is None or is_one_hour_ago(lastDone):  # Write is_one_hour_ago()
        # Do things
        lastDone = time.now() # Not a real function yet
    else:
        sleep(600)  # Sleep for a minute and check again

is_one_hour_ago probably needs the datetime module, but is relatively simple logic once you get it written (return True if now minus one hour >= lastDone else False), and you'll need to look at python's datetime module. Or time's clock.

It is notable that the interpreter can't run while your computer sleeps, but it will run immediately after you open it, and it'll be accurate through sleeps aside from that.

Upvotes: 3

Related Questions