Last active
May 19, 2023 11:19
-
-
Save ivelin/6a14002b623ec8b53e9987a952ff95cc to your computer and use it in GitHub Desktop.
Python good process kill
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def _process_kill(pid, signal=0): | |
"""Send a signal to a process. | |
:Returns: | |
---------- | |
True if the pid is dead | |
with no signal argument, sends no signal. | |
""" | |
# if 'ps --no-headers' returns no lines, the pid is dead | |
from os import kill | |
try: | |
return kill(pid, signal) | |
except OSError as e: | |
# process is dead | |
if e.errno == 3: | |
return True | |
# no permissions | |
elif e.errno == 1: | |
return False | |
else: | |
raise e | |
def _process_dead(pid): | |
if _process_kill(pid): | |
return True | |
# maybe the pid is a zombie that needs us to wait4 it | |
from os import waitpid, WNOHANG | |
try: | |
dead = waitpid(pid, WNOHANG)[0] | |
except OSError as e: | |
# pid is not a child | |
if e.errno == 10: | |
log.warning("Process PID %s not a child. Can't kill it." % pid) | |
return False | |
else: | |
raise e | |
return dead | |
# def kill(pid, sig=0): pass #DEBUG: test hang condition | |
def process_goodkill(pid, interval=1, hung=20): | |
"""Let process die gracefully. | |
Gradually send harsher signals | |
if necessary. | |
:Returns: | |
--------- | |
True if the process was killed and exited cleanly. | |
False if the process kill hung up and couldn't be cleaned. | |
""" | |
from signal import SIGTERM, SIGINT, SIGHUP, SIGKILL | |
from time import sleep | |
for signal in [SIGTERM, SIGINT, SIGHUP]: | |
if _process_kill(pid, signal): | |
return | |
if _process_dead(pid): | |
return | |
sleep(interval) | |
i = 0 | |
while True: | |
# infinite-loop protection | |
if i < hung: | |
i += 1 | |
else: | |
log.warning("Process PID %s is hung. Giving up kill." % pid) | |
return | |
if _process_kill(pid, SIGKILL): | |
return | |
if _process_dead(pid): | |
return | |
sleep(interval) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment