19

In python, if I want to keep a process or thread running forever, I can typically do this with an empty while loop:

while 1: pass 

This, however, will eat an unfair amount of CPU process. Adding a short sleep would work:

import time while 1: time.sleep(0.01) 

Is there any best or cleaner way of doing this?

5
  • What is the thread waiting for? Why don't you do time.sleep(1000000)? Commented Jul 12, 2010 at 7:44
  • it's for a server-like application, so i'd like it to wait for more than days (1000000 seconds)! theoretically a thread that has to run forever has to keep running for a much longer time than a very high number of seconds Commented Jul 12, 2010 at 7:59
  • 1
    Is the thread doing anything useful other than sleeping or busy-looping? If not, can you just do away with it? And if it is doing something worthwhile, 'fess up! That's the bit that we need to know about to help you. Commented Jul 12, 2010 at 9:17
  • 1
    it is not doing a thing apart from keeping the process running so that its subprocesses can keep working Commented Jul 12, 2010 at 10:09
  • 3
    I doubt that this is necessary since subprocesses can be detached from their parent processes. However, while True: time.sleep(0x7FFFFFFF) should work. Commented Jul 12, 2010 at 12:29

6 Answers 6

14

Given the rather bizarre requirements (a process that goes forever without using much CPU), this is reasonably compact:

import threading dummy_event = threading.Event() dummy_event.wait() 

...however, I fear I am succumbing to the temptation to solve your Y and not your X.

Besides which, this won't work if your platform doesn't provide the threading module. If you try to substitute the dummy_threading module, dummy_event.wait() returns immediately.

Update: if you are just keeping a parent process going for the sake of its subprocesses, you can use the wait()method on Popen objects, or the join() method on Process objects. Both of these methods will block indefinitely until the subprocess ends. If you're using some other subprocess API, there's bound to be equivalent functionality available. If not, get the PID of the process and use os.waitpid().

Sign up to request clarification or add additional context in comments.

Comments

3

Don't use busy waiting. Depending on what you are waiting for, use one of the operating system's blocking wait functions, e.g. select on Unix and WaitForSingleObject/WaitForMultipleObjects on Windows.

1 Comment

thanks for the answer. though, i'm not waiting for a thing. as the question implies, the process aim is to run forever until it's killed.
3

If you are relying on this script to perform periodic maintenance, use cron (UNIX) or scheduled tasks (Windows).

If you wish to wait for subprocesses to complete, use os.waitpid.

If you wish to wait for filesystem activity, use pyinotify.

Comments

1

Someone might end up to this old question so I'll be leaving this here. The optimal way is a BlockingScheduler from apscheduler module with which you also get to schedule jobs in regular intervals (or cron like or whatever)

from datetime import datetime import os from apscheduler.schedulers.blocking import BlockingScheduler def tick(): print('Tick! The time is: %s' % datetime.now()) if __name__ == '__main__': scheduler = BlockingScheduler() scheduler.add_job(tick, 'interval', seconds=3) print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C')) try: scheduler.start() except (KeyboardInterrupt, SystemExit): pass 

2 Comments

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
I'll edit the comment asap thanks
0

What's the issue with sleeping for a very brief period of time? 1 millisecond is close to an eternity to a modern computer. Provided you don't have thousands of these threads (which it sounds like you don't), then there is NOTHING wrong with sleeping for one, ten, ten thousand, or ten million milliseconds every iteration through the loop. The CPU won't even notice this little blip.

2 Comments

Bad practice to wait with a while loop. Your answer is similar to “what’s wrong with a tiny burning car tire for a short period of time?”. If there weren’t any other options. But there are. Plenty. And the question was for a cleaner way to do things.
It would be wrong on any computer running off of a battery to force it to wake up every millisecond for no reason. The less you wake the machine up, the longer the battery lasts.
0

This uses the asyncio technique similar to the answer in https://stackoverflow.com/a/60631484/242042.

Deriving from the answer at Python asyncio: event loop does not seem to stop when stop method is called this is how I did it on my AHK mapping script

import asyncio loop = asyncio.get_event_loop() def stop_loop(): """ This can be called from another thread to schedule stopping the event loop """ loop.call_soon_threadsafe(loop.stop) try: loop.run_forever() finally: loop.close() 

The advantage to this aside from the while True: sleep approach is it provides a more or less consistent approach to handling termination of the app not just CtrlC or an explicit condition check.

In addition instead of sleep it uses select internally based on the answer to my other question https://stackoverflow.com/a/78465221/242042 and per the comment of the person providing the answer select will block without taking any resources.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.