102

I need to run my Python program forever in an infinite loop..

Currently I am running it like this -

#!/usr/bin/python

import time

# some python code that I want 
# to keep on running


# Is this the right way to run the python program forever?
# And do I even need this time.sleep call?
while True:
    time.sleep(5)

Is there any better way of doing it? Or do I even need time.sleep call? Any thoughts?

martineau
  • 119,623
  • 25
  • 170
  • 301
  • That would be the right way to do it. You don't need the `time.sleep(5)`, as long as you have some code indented below the `while True:` line (it can just be `pass` at a minimum) – Holy Mackerel Nov 24 '13 at 02:08
  • 1
    Its good to add a break condition -"shutdown hook", if you want to exit, rather than killing the process. – user3020494 Nov 24 '13 at 02:12
  • 8
    But if you don't sleep, or do something which sleeps for an external event (like listening for connections or data on a socket) then your program will use 100% CPU, aka [busywait](http://en.wikipedia.org/wiki/Busy_waiting). This is not polite :) – qris Feb 20 '15 at 10:41
  • Python 3.5 can use asyncio and bind functions to events. Program with GUI can deal with ui-event loop ( for example gtk.main() ) – eri Mar 02 '17 at 18:44

8 Answers8

115

Yes, you can use a while True: loop that never breaks to run Python code continually.

However, you will need to put the code you want to run continually inside the loop:

#!/usr/bin/python

while True:
    # some python code that I want 
    # to keep on running

Also, time.sleep is used to suspend the operation of a script for a period of time. So, since you want yours to run continually, I don't see why you would use it.

martineau
  • 119,623
  • 25
  • 170
  • 301
  • while True doesn't seem to work when launching python code via a .bat file – BossRoyce May 17 '19 at 17:32
  • 2
    May `time.sleep` improve performance by waiting for example 1ms instead of running at its max speed ? – TOPKAT Oct 06 '19 at 13:10
  • @GLAND_PROPRE: Improve the performance of what? – martineau May 01 '21 at 08:30
  • @martineau I am sorry, I am from a Javascript background where if you don't put a "frame limit", the `while` loop freezes the process, consumming all the CPU. So I was immagining that putting a 1ms `time.sleep` between each iterations would avoid the process to consume all it's CPU. But I think I don't exactly understand how this is handled in python... – TOPKAT May 03 '21 at 07:52
47

How about this one?

import signal
signal.pause()

This will let your program sleep until it receives a signal from some other process (or itself, in another thread), letting it know it is time to do something.

roarsneer
  • 624
  • 6
  • 8
21

I know this is too old thread but why no one mentioned this

#!/usr/bin/python3
import asyncio 

loop = asyncio.get_event_loop()
try:
    loop.run_forever()
finally:
    loop.close()
A J Brockberg
  • 563
  • 2
  • 5
  • 18
  • 1
    I always use this when trying to make my program run forever. I don't know why nobody mentioned this either – madladzen Aug 21 '20 at 20:32
  • 11
    How is it any better? I mean, if simple `while True:` can do the job why bother including a library. If there are any pros/cons, please update your answer to include details. – Yogesh Sep 15 '21 at 07:51
  • 1
    Similar to Yogesh I'd like to know the rationale here. – jason m Feb 15 '22 at 16:06
15

sleep is a good way to avoid overload on the cpu

not sure if it's really clever, but I usually use

while(not sleep(5)):
    #code to execute

sleep method always returns None.

Miriam Farber
  • 18,986
  • 14
  • 61
  • 76
NIEL Alexandre
  • 527
  • 4
  • 8
  • 2
    downvoted with no comment? I liked this solution when I read it, because it has good readibility/maintainability. An interested reader of this code does not need to go scrolling to find the loop interval. – Matt Sep 14 '18 at 14:31
  • 1
    @mustafa which one ? explain yourself, it works perfectly fine. – NIEL Alexandre Dec 31 '18 at 08:08
  • 6
    doesn't it sleep before first execution? I don't think it is desired behavior in general – noonex May 20 '19 at 09:56
6

Here is the complete syntax,

#!/usr/bin/python3

import time 

def your_function():
    print("Hello, World")

while True:
    your_function()
    time.sleep(10) #make function to sleep for 10 seconds
Balaji.J.B
  • 618
  • 7
  • 14
4

for OS's that support select:

import select

# your code

select.select([], [], [])
gnr
  • 2,324
  • 1
  • 22
  • 24
1

I have a small script interruptableloop.py that runs the code at an interval (default 1sec), it pumps out a message to the screen while it's running, and traps an interrupt signal that you can send with CTL-C:

#!/usr/bin/python3
from interruptableLoop import InterruptableLoop

loop=InterruptableLoop(intervalSecs=1) # redundant argument
while loop.ShouldContinue():
   # some python code that I want 
   # to keep on running
   pass

When you run the script and then interrupt it you see this output, (the periods pump out on every pass of the loop):

[py36]$ ./interruptexample.py
CTL-C to stop   (or $kill -s SIGINT pid)
......^C
Exiting at  2018-07-28 14:58:40.359331

interruptableLoop.py:

"""
    Use to create a permanent loop that can be stopped ...

    ... from same terminal where process was started and is running in foreground: 
        CTL-C

    ... from same user account but through a different terminal 
        $ kill -2 <pid> 
        or $ kill -s SIGINT <pid>

"""
import signal
import time
from datetime import datetime as dtt
__all__=["InterruptableLoop",]
class InterruptableLoop:
    def __init__(self,intervalSecs=1,printStatus=True):
        self.intervalSecs=intervalSecs
        self.shouldContinue=True
        self.printStatus=printStatus
        self.interrupted=False
        if self.printStatus:
            print ("CTL-C to stop\t(or $kill -s SIGINT pid)")
        signal.signal(signal.SIGINT, self._StopRunning)
        signal.signal(signal.SIGQUIT, self._Abort)
        signal.signal(signal.SIGTERM, self._Abort)

    def _StopRunning(self, signal, frame):
        self.shouldContinue = False

    def _Abort(self, signal, frame):
        raise 

    def ShouldContinue(self):
        time.sleep(self.intervalSecs)
        if self.shouldContinue and self.printStatus: 
            print( ".",end="",flush=True)
        elif not self.shouldContinue and self.printStatus:
            print ("Exiting at ",dtt.now())
        return self.shouldContinue
Rian Rizvi
  • 9,989
  • 2
  • 37
  • 33
  • Wouldn't it be a lot easier (and more Pythonic) to just catch the [`KeyboardInterrupt`](https://docs.python.org/3/library/exceptions.html#KeyboardInterrupt) and [`SystemExit`](https://docs.python.org/3/library/exceptions.html#SystemExit) exceptions in the client code, rather than have a dedicated class for it? – Matthew Cole Jan 07 '20 at 22:09
  • I use this for encapsulation, and I like the way it reads. Obviously the implementation of *interruptableloop* doesn’t run through my mind when I’m using it. – Rian Rizvi Jan 08 '20 at 00:50
0

If you mean run as service then you can use any rest framework

from flask import Flask
class A:
    def one(port):
        app = Flask(__name__)
        app.run(port = port)
        

call it:

one(port=1001)

it will always keep listening on 1001

 * Running on http://127.0.0.1:1001/ (Press CTRL+C to quit)
Akhilesh
  • 89
  • 1
  • 6