def _installSignalHandlers(self):
supportedSignals = [signal.SIGINT, signal.SIGTERM]
if hasattr(signal, 'SIGHUP'):
supportedSignals.append(signal.SIGHUP)
self._oldSIGs = [(x,signal.getsignal(x)) for x in supportedSignals]
for sig in supportedSignals:
if hasattr(signal, 'SIGHUP') and sig == signal.SIGHUP:
signal.signal(sig, self._hupHandler)
else:
signal.signal(sig, self._intHandler)
python类SIGHUP的实例源码
def _installSignalHandlers(self):
supportedSignals = [signal.SIGINT, signal.SIGTERM]
if hasattr(signal, 'SIGHUP'):
supportedSignals.append(signal.SIGHUP)
self._oldSIGs = [(x,signal.getsignal(x)) for x in supportedSignals]
for sig in supportedSignals:
if hasattr(signal, 'SIGHUP') and sig == signal.SIGHUP:
signal.signal(sig, self._hupHandler)
else:
signal.signal(sig, self._intHandler)
def _sighup_supported():
return hasattr(signal, 'SIGHUP')
def _is_sighup_and_daemon(signo):
if not (_sighup_supported() and signo == signal.SIGHUP):
# Avoid checking if we are a daemon, because the signal isn't
# SIGHUP.
return False
return _is_daemon()
def _signo_to_signame(signo):
signals = {signal.SIGTERM: 'SIGTERM',
signal.SIGINT: 'SIGINT'}
if _sighup_supported():
signals[signal.SIGHUP] = 'SIGHUP'
return signals[signo]
def _set_signals_handler(handler):
signal.signal(signal.SIGTERM, handler)
signal.signal(signal.SIGINT, handler)
if _sighup_supported():
signal.signal(signal.SIGHUP, handler)
def _child_process_handle_signal(self):
# Setup child signal handlers differently
def _sigterm(*args):
signal.signal(signal.SIGTERM, signal.SIG_DFL)
raise SignalExit(signal.SIGTERM)
def _sighup(*args):
signal.signal(signal.SIGHUP, signal.SIG_DFL)
raise SignalExit(signal.SIGHUP)
signal.signal(signal.SIGTERM, _sigterm)
if _sighup_supported():
signal.signal(signal.SIGHUP, _sighup)
# Block SIGINT and let the parent send us a SIGTERM
signal.signal(signal.SIGINT, signal.SIG_IGN)
def main():
global rolld_proc, nginx_proc
# start rolld
rolld_proc = Subprocess(
shlex.split("rolld example/rolld.yaml"),
stdout=Subprocess.STREAM,
stderr=Subprocess.STREAM,
)
out = partial(out_fn, name='rolld')
rolld_proc.stdout.read_until_close(exit_callback, streaming_callback=out)
rolld_proc.stderr.read_until_close(exit_callback, streaming_callback=out)
# start nginx on port 9091
nginx_proc = Subprocess(
shlex.split("""nginx -p "%s" -c example/nginx.conf""" % os.path.curdir),
stdout=Subprocess.STREAM,
stderr=Subprocess.STREAM,
)
out = partial(out_fn, name='rolld')
nginx_proc.stdout.read_until_close(exit_callback, streaming_callback=out)
nginx_proc.stderr.read_until_close(exit_callback, streaming_callback=out)
# now we restart everything
def send_hub_to_rolld():
print "sending SIGHUP to rolld"
os.kill(rolld_proc.pid, signal.SIGHUP)
def start_ping():
global periodic_checker
periodic_checker = PeriodicCallback(partial(periodic_callback, proc_pid=rolld_proc.pid), 1000)
periodic_checker.start()
IOLoop.instance().add_timeout(time.time() + 5, start_ping)
IOLoop.instance().add_timeout(time.time() + 15, send_hub_to_rolld)
IOLoop.instance().add_timeout(time.time() + 55, exit_test)
def reload(self):
"""Reloading of the service
This method will be executed when the Service receives a SIGHUP.
If not implemented the process will just end with status 0 and
:py:class:`ServiceRunner` will start a new fresh process for this
service with the same worker_id.
"""
self._clean_exit()
def __init__(self, wait_interval=0.01):
"""Creates the ServiceManager object
:param wait_interval: time between each new process spawn
:type wait_interval: float
"""
if self._process_runner_already_created:
raise RuntimeError("Only one instance of ProcessRunner per "
"application is allowed")
ServiceManager._process_runner_already_created = True
self._wait_interval = wait_interval
self._shutdown = threading.Event()
self._running_services = collections.defaultdict(dict)
self._services = []
self._forktimes = []
self._current_process = None
# Try to create a session id if possible
try:
os.setsid()
except OSError:
pass
self.readpipe, self.writepipe = os.pipe()
signal.signal(signal.SIGTERM, self._clean_exit)
signal.signal(signal.SIGINT, self._fast_exit)
signal.signal(signal.SIGALRM, self._alarm_exit)
signal.signal(signal.SIGHUP, self._reload_services)
def _reload_services(self, *args, **kwargs):
if self._shutdown.is_set():
# NOTE(sileht): We are in shutdown process no need
# to reload anything
return
# Reset forktimes to respawn services quickly
self._forktimes = []
signal.signal(signal.SIGHUP, signal.SIG_IGN)
os.killpg(0, signal.SIGHUP)
signal.signal(signal.SIGHUP, self._reload_services)
def __init__(self, loop, filename, verbose):
self._running_objects = {}
self._running_coros = set()
self._running_cleanups = set()
self._http_handlers = {}
self.filename = filename
self.verbose = verbose
self.tasks = {}
self.task_set = set()
self.loop = loop
self.providers = {}
self.task_start_handlers = []
self.task_end_handlers = []
self.job_end_handlers = []
self.job_update_handlers = []
self.stop_event = asyncio.Event(loop=loop)
self.reload_event = asyncio.Event(loop=loop)
loop.add_signal_handler(signal.SIGINT, self.stop)
loop.add_signal_handler(signal.SIGHUP, self.reload_event.set)
self.task_event_map = {}
self.eventid_event_map = {}
self._services = []
def stop(self):
self.loop.remove_signal_handler(signal.SIGINT)
self.loop.remove_signal_handler(signal.SIGHUP)
self.stop_event.set()
def __init__(self):
# initially set the standard logger
self.set_logger(logging.getLogger(__name__))
# initially set an empty configuration
self.set_config(configparser.ConfigParser())
# set up the quit signals
self.setup_signals(
signals = [signal.SIGINT, signal.SIGTERM, signal.SIGHUP],
handler = self.please_stop_now
)
# use glib as default mailoop for dbus
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
dbus.mainloop.glib.threads_init()
GLib.threads_init()
self.loop = GLib.MainLoop() # create mainloop
self.systembus = dbus.SystemBus() # the system bus
self.systembus.request_name(CO2MONITOR_BUSNAME) # request the bus name
bus_name = dbus.service.BusName(CO2MONITOR_BUSNAME, self.systembus) # create bus name
# register the object on the bus name
dbus.service.Object.__init__(self, bus_name, CO2MONITOR_OBJECTPATH)
def __init__(self):
# initially set the standard logger
self.set_logger(logging.getLogger(__name__))
# initially set an empty configuration
self.set_config(configparser.ConfigParser())
# set up the quit signals
self.setup_signals(
signals = [signal.SIGINT, signal.SIGTERM, signal.SIGHUP],
handler = self.quit
)
def daemon_start(pid_file, log_file):
def handle_exit(signum, _):
if signum == signal.SIGTERM:
sys.exit(0)
sys.exit(1)
signal.signal(signal.SIGINT, handle_exit)
signal.signal(signal.SIGTERM, handle_exit)
# fork only once because we are sure parent will exit
pid = os.fork()
assert pid != -1
if pid > 0:
# parent waits for its child
time.sleep(5)
sys.exit(0)
# child signals its parent to exit
ppid = os.getppid()
pid = os.getpid()
if write_pid_file(pid_file, pid) != 0:
os.kill(ppid, signal.SIGINT)
sys.exit(1)
os.setsid()
signal.signal(signal.SIG_IGN, signal.SIGHUP)
print('started')
os.kill(ppid, signal.SIGTERM)
sys.stdin.close()
try:
freopen(log_file, 'a', sys.stdout)
freopen(log_file, 'a', sys.stderr)
except IOError as e:
shell.print_exception(e)
sys.exit(1)
def send_signals():
pid = os.getpid()
print('starting send_signals for {}'.format(pid))
for name in ['SIGHUP', 'SIGHUP', 'SIGUSR1', 'SIGINT']:
print('sending {}'.format(name))
os.kill(pid, getattr(signal, name))
# Yield control to allow the signal handler to run,
# since the signal does not interrupt the program
# flow otherwise.
print('yielding control')
await asyncio.sleep(0.01)
return
def test_subprocess_send_signal(self):
prog = os.path.join(os.path.dirname(__file__), 'echo.py')
connect = self.loop.subprocess_exec(
functools.partial(MySubprocessProtocol, self.loop),
sys.executable, prog)
transp, proto = self.loop.run_until_complete(connect)
self.assertIsInstance(proto, MySubprocessProtocol)
self.loop.run_until_complete(proto.connected)
transp.send_signal(signal.SIGHUP)
self.loop.run_until_complete(proto.completed)
self.assertEqual(-signal.SIGHUP, proto.returncode)
transp.close()
def test_add_signal_handler(self, m_signal):
m_signal.NSIG = signal.NSIG
cb = lambda: True
self.loop.add_signal_handler(signal.SIGHUP, cb)
h = self.loop._signal_handlers.get(signal.SIGHUP)
self.assertIsInstance(h, asyncio.Handle)
self.assertEqual(h._callback, cb)
def test_add_signal_handler_install_error2(self, m_logging, m_signal):
m_signal.NSIG = signal.NSIG
class Err(OSError):
errno = errno.EINVAL
m_signal.signal.side_effect = Err
self.loop._signal_handlers[signal.SIGHUP] = lambda: True
self.assertRaises(
RuntimeError,
self.loop.add_signal_handler,
signal.SIGINT, lambda: True)
self.assertFalse(m_logging.info.called)
self.assertEqual(1, m_signal.set_wakeup_fd.call_count)