为什么signal.SIGTERM在主线程中没有正确处理?

时间:2013-11-14 21:25:40

标签: python multithreading sigterm

我有连续运行的python代码(收集传感器数据)。它应该使用start-stop-daemon在启动时启动。但是,我希望能够优雅地终止进程,所以我从帖子How to process SIGTERM signal gracefully?中的建议开始,并将我的主循环放在一个单独的线程中。我希望能够在它作为一个守护进程运行时优雅地关闭它(start-stop-daemon将发送一个终止信号),当我自己启动它以便在终端中进行测试时(我按下{{ 1}})。

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

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

ctrl-c

1 个答案:

答案 0 :(得分: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)"