4

我有连续运行的python代码(收集传感器数据)。它应该在启动时使用start-stop-daemon. 但是,我希望能够优雅地终止进程,所以我从如何优雅地处理 SIGTERM 信号?并将我的主循环放在一个单独的线程中。我希望能够在它作为守护进程运行时(start-stop-daemon将发送终止信号)和我自己在终端中短暂启动它以进行测试(我按ctrl-c)优雅地关闭它。

但是,如果我终止进程,似乎不会调用信号处理程序(即使不使用线程,“ done (killed)”也不会出现在我重定向到的文件中)。当我按下 时ctrl-c,收集会继续并在终端(或我重定向到的文件)中保持打印数据。

我在下面的代码中做错了什么?

from threading import Thread
import time, sys, signal

shutdown_flag = False #used for gracefull shutdown 

def main_loop():
    while not shutdown_flag:
        collect_data() # contains some print "data" statements
        time.sleep(5)
    print "done (killed)"

def sighandler(signum, frame):
    print 'signal handler called with signal: %s ' % signum
    global shutdown_flag
    shutdown_flag = True

def main(argv=None):
    signal.signal(signal.SIGTERM, sighandler) # so we can handle kill gracefully
    signal.signal(signal.SIGINT, sighandler) # so we can handle ctrl-c
    try:
        Thread(target=main_loop, args=()).start()
    except Exception, reason:
        print reason

if __name__ == '__main__':
    sys.exit(main(sys.argv))
4

1 回答 1

4

您正在使用以下语句终止主线程:

if __name__ == '__main__':
    sys.exit(main(sys.argv))

所以你的信号处理程序永远不会运行。信号处理程序是主线程的一部分,而不是main_loop您创建的线程。所以一旦主线程退出,就没有信号处理函数可以调用了。

你需要这样的东西:

def sighandler(signum, frame):
    print 'signal handler called with signal: %s ' % signum
    global shutdown_flag
    shutdown_flag = True
    sys.exit() # make sure you add this so the main thread exits as well.

if __name__ == '__main__':
    main(sys.argv)
    while 1:  # this will force your main thread to live until you terminate it.
       time.sleep(1) 

一个简单的测试来看看你的程序中有多少线程正在运行:

def main_loop():
    while not shutdown_flag:
        collect_data() # contains some print "data" statements
        time.sleep(5)
        import threading
        print threading.enumerate()
    print "done (killed)"
于 2013-11-14T21:27:24.557 回答