简体   繁体   English

Python - 在后台运行的无限循环脚本+重启

[英]Python - Infinite loop script running in background + restart

I would like to have a python script that runs in background (infinite loop). 我想有一个在后台运行的python脚本(无限循环)。

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 我想删除我不需要的time.sleep(1)

  2. I would like to run the script in background nohup python myscript.py & is there a way to kill it "gracefully"? 我想在后台运行脚本nohup python myscript.py &有没有办法“优雅地”杀死它? 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? 当我运行它时,通常my.cleanup() CTRL + C my.cleanup() ,有没有办法在使用kill命令时调用它?

  3. What if I would like (using cron) kill the script and restart it again? 如果我想(使用cron)杀死脚本并重新启动它会怎么样? Is there a way to make it do my.cleanup() ? 有没有办法让它做my.cleanup()

Thank you 谢谢

  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 我想删除我不需要的time.sleep(1)

A while True or while <condition> loop is OK, in my opinion. 在我看来, while True或者while <condition>循环是好的。

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. 只要您不需要程序等待一段时间, sleep()就不是必需的。

  1. I would like to run the script in background nohup python myscript.py & is there a way to kill it "gracefully"? 我想在后台运行脚本nohup python myscript.py&有没有办法“优雅地”杀死它? 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? 当我运行它时,通常按下CTRL + C调用my.cleanup(),有没有办法在使用kill命令时调用它?

You may want to "listen" to serveral signals using the signal() method from the package " signal ". 您可能希望使用“ signal ”包中的signal()方法“监听”多个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. 请注意,您无法收听SIGKILL ,在使用该信号终止程序时,您没有机会进行任何清理。 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? 如果我想(使用cron)杀死脚本并重新启动它会怎么样? Is there a way to make it do my.cleanup()? 有没有办法让它做my.cleanup()?

As long as your cronjob will kill the program with any signal except SIGKILL this is possible, of course. 当然,只要你的cronjob会用除SIGKILL之外的任何信号杀死程序,这是可能的。

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). 您应该考虑以不同的方式执行您想要执行的操作:例如,如果您想在无限循环任务之前“重新执行”某些设置任务,您也可以在某个信号上执行此操作(某些程序使用SIGHUP执行此操作)例如,重新加载配置。 You'd have to break the loop, do the task and resume it. 你必须打破循环,完成任务并恢复它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM