5

I would like to have a python script that runs in background (infinite loop).

def main():
    # inizialize and start threads
    [...]

    try:
        while True:
            time.sleep(1)

    except KeyboardInterrupt:
        my.cleanup()

if __name__ == '__main__':
    main()
    my.cleanup()
  1. In order to have the application run constantly in infinite loop what is the best way? I want to remove the time.sleep(1) which I don't need

  2. I would like to run the script in background nohup python myscript.py & is there a way to kill it "gracefully"? When I run it normally hitting the CTRL+C my.cleanup() is called, is there a way to call this when the kill command is used?

  3. What if I would like (using cron) kill the script and restart it again? Is there a way to make it do my.cleanup()?

Thank you

2
  • Have you considered using Celery? It can run workers in the background on an interval and you can start/stop workers through shell or GUI. Commented May 16, 2015 at 14:39
  • @nivixzixer celery doesnt do websocket data, I want an infinite loop to listen to websocket data or redis pub channels Commented Mar 7, 2019 at 6:33

1 Answer 1

4
  1. In order to have the application run constantly in infinite loop what is the best way? I want to remove the time.sleep(1) which I don't need

A while True or while <condition> loop is OK, in my opinion.

A sleep() is not mandatory for such a infinite loop as long as you don't require your program to wait for a certain time period.

  1. I would like to run the script in background nohup python myscript.py & is there a way to kill it "gracefully"? When I run it normally hitting the CTRL+C my.cleanup() is called, is there a way to call this when the kill command is used?

You may want to "listen" to serveral signals using the signal() method from the package "signal".

Simplified example extended by signal hooks:

import time
import signal

# determines if the loop is running
running = True

def cleanup():
  print "Cleaning up ..."

def main():
  global running

  # add a hook for TERM (15) and INT (2)
  signal.signal(signal.SIGTERM, _handle_signal)
  signal.signal(signal.SIGINT, _handle_signal)

  # is True by default - will be set False on signal
  while running:
    time.sleep(1)

# when receiving a signal ...
def _handle_signal(signal, frame):
  global running

  # mark the loop stopped
  running = False
  # cleanup
  cleanup()

if __name__ == '__main__':
  main()

Note, that you can't listen to SIGKILL, when terminating a program using that signal, you have no chance to do any clean up. Your program should be aware of that (an do kind of pre-start clean up or fail with a proper message).

Note, I was using a global variable to keep this example simple, I prefer to encapsulate this in a custom class.

  1. What if I would like (using cron) kill the script and restart it again? Is there a way to make it do my.cleanup()?

As long as your cronjob will kill the program with any signal except SIGKILL this is possible, of course.

You should consider doing what you want to do in a different way: for example, if you want to "re-do" some setup task before the infinite loop task, you could also do this upon a certain signal (some programs use SIGHUP for reloading configrations, for example). You'd have to break the loop, do the task and resume it.

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

3 Comments

Thank you for your reply. This helped a lot! Two more questions: 1. I don't need the sleep() I just need to keep the script alive, what normal developers do? 2. except KeyboardInterrupt: is than useless using this: signal.signal(signal.SIGINT, _handle_signal) right?
You're right, the except KeyboardInterrupt is superflous. I also moved the signal handler registration to main(). I'm not sure what you mean with your first question. Don't you need to do any tasks within that loop?
Thank you, no actually not, I just need the script not to exit

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.