【发布时间】:2014-09-05 00:12:18
【问题描述】:
这应该很简单,我很惊讶我无法在 stackoverflow 上找到已经回答的问题。
我有一个类似守护进程的程序,它需要响应 SIGTERM 和 SIGINT 信号才能与 upstart 一起正常工作。我读到最好的方法是在与主线程不同的线程中运行程序的主循环,并让主线程处理信号。然后,当接收到信号时,信号处理程序应该通过设置一个在主循环中例行检查的哨兵标志来告诉主循环退出。
我已经尝试过这样做,但它没有按我预期的方式工作。请看下面的代码:
from threading import Thread
import signal
import time
import sys
stop_requested = False
def sig_handler(signum, frame):
sys.stdout.write("handling signal: %s\n" % signum)
sys.stdout.flush()
global stop_requested
stop_requested = True
def run():
sys.stdout.write("run started\n")
sys.stdout.flush()
while not stop_requested:
time.sleep(2)
sys.stdout.write("run exited\n")
sys.stdout.flush()
signal.signal(signal.SIGTERM, sig_handler)
signal.signal(signal.SIGINT, sig_handler)
t = Thread(target=run)
t.start()
t.join()
sys.stdout.write("join completed\n")
sys.stdout.flush()
我通过以下两种方式对此进行了测试:
1)
$ python main.py > output.txt&
[2] 3204
$ kill -15 3204
2)
$ python main.py
ctrl+c
在这两种情况下,我都希望将其写入输出:
run started
handling signal: 15
run exited
join completed
在第一种情况下,程序退出,但我看到的只是:
run started
在第二种情况下,当按下 ctrl+c 并且程序没有退出时,SIGTERM 信号似乎被忽略了。
我在这里错过了什么?
【问题讨论】:
-
尝试将
t.join()替换为while t.is_alive(): t.join(1)。您的主线程将每秒唤醒一次以检查信号。
标签: python linux multithreading