在Linux下的Python 2.6,我可以使用以下方法來處理TERM信號:Python的 - 捕獲所有信號
import signal
def handleSigTERM():
shutdown()
signal.signal(signal.SIGTERM, handleSigTERM)
有什麼辦法來設置由進程接收的所有信號的處理,比其他一次只設置一次?
在Linux下的Python 2.6,我可以使用以下方法來處理TERM信號:Python的 - 捕獲所有信號
import signal
def handleSigTERM():
shutdown()
signal.signal(signal.SIGTERM, handleSigTERM)
有什麼辦法來設置由進程接收的所有信號的處理,比其他一次只設置一次?
您可以循環訪問信號模塊中的信號並設置它們。
for i in [x for x in dir(signal) if x.startswith("SIG")]:
try:
signum = getattr(signal,i)
signal.signal(signum,sighandler)
except (OSError, RuntimeError) as m: #OSError for Python3, RuntimeError for 2
print ("Skipping {}".format(i))
正是我在找的,謝謝! – 2010-01-27 17:51:39
不客氣。感謝您修復程序中的錯誤。 :) – 2010-01-27 17:54:07
這應該是RuntimeError,而不是RunTimeError。無法編輯,只是一個字符的變化。 – tobych 2011-09-01 04:14:55
如果你想擺脫這種嘗試,只需忽略無法捕獲的信號。
#!/usr/bin/env python
# https://stackoverflow.com/questions/2148888/python-trap-all-signals
import os
import sys
import time
import signal
SIGNALS_TO_NAMES_DICT = dict((getattr(signal, n), n) \
for n in dir(signal) if n.startswith('SIG') and '_' not in n)
def receive_signal(signum, stack):
if signum in [1,2,3,15]:
print 'Caught signal %s (%s), exiting.' % (SIGNALS_TO_NAMES_DICT[signum], str(signum))
sys.exit()
else:
print 'Caught signal %s (%s), ignoring.' % (SIGNALS_TO_NAMES_DICT[signum], str(signum))
def main():
uncatchable = ['SIG_DFL','SIGSTOP','SIGKILL']
for i in [x for x in dir(signal) if x.startswith("SIG")]:
if not i in uncatchable:
signum = getattr(signal,i)
signal.signal(signum,receive_signal)
print('My PID: %s' % os.getpid())
while True:
time.sleep(1)
main()
代碼沒有正確縮進,但我無法編輯它,因爲不要讓我做出那麼小的更改。所有的for應該縮進一個縮進級別。 – krenel00 2013-05-10 15:04:55
該代碼不適用於當前版本的python。以SIG開頭的變量有許多相同的值。例如,SIGHUP和SIG_UNBLOCK都是1.我能想到得到實際信號列表的唯一方法就是自己做。
from signal import *
signals = {
SIGABRT: 'SIGABRT',
SIGALRM: 'SIGALRM',
SIGBUS: 'SIGBUS',
SIGCHLD: 'SIGCHLD',
SIGCONT: 'SIGCONT',
SIGFPE: 'SIGFPE',
SIGHUP: 'SIGHUP',
SIGILL: 'SIGILL',
SIGINT: 'SIGINT',
SIGPIPE: 'SIGPIPE',
SIGPOLL: 'SIGPOLL',
SIGPROF: 'SIGPROF',
SIGQUIT: 'SIGQUIT',
SIGSEGV: 'SIGSEGV',
SIGSYS: 'SIGSYS',
SIGTERM: 'SIGTERM',
SIGTRAP: 'SIGTRAP',
SIGTSTP: 'SIGTSTP',
SIGTTIN: 'SIGTTIN',
SIGTTOU: 'SIGTTOU',
SIGURG: 'SIGURG',
SIGUSR1: 'SIGUSR1',
SIGUSR2: 'SIGUSR2',
SIGVTALRM: 'SIGVTALRM',
SIGXCPU: 'SIGXCPU',
SIGXFSZ: 'SIGXFSZ',
}
for num in signals:
signal(num, h)
這沒有必要。所有的信號仍然以'SIG'開始,但你需要添加一個雙重檢查以確保你忽略了'SIG_'。 – 2017-05-26 11:25:12
對於Python 3.5,信號常數defined as an enum,實現了更好的途徑:
import signal
catchable_sigs = set(signal.Signals) - {signal.SIGKILL, signal.SIGSTOP}
for sig in catchable_sigs:
signal.signal(sig, print) # Substitute handler of choice for `print`
請問downvoter請留言?這個答案有什麼問題嗎? – doctaphred 2016-04-23 11:15:14
這裏的不作爲有許多陷阱的其他2/3兼容的方式:
from itertools import count
import signal
def set_all_signal_signals(handler):
"""Set all signals to a particular handler."""
for signalnum in count(1):
try:
signal.signal(signalnum, handler)
print("set {}".format(signalnum))
except (OSError, RuntimeError):
# Invalid argument such as signals that can't be blocked
pass
except ValueError:
# Signal out of range
break
由於signalnum
只是一個數字,所以迭代超過1將信號設置爲特定的句柄。
我相信答案會是「否」,某些信號甚至不能被捕獲(SIGKILL)。 – 2010-01-27 17:22:32