-
Notifications
You must be signed in to change notification settings - Fork 1
进程管理
HouJie edited this page May 30, 2019
·
1 revision
这一部分主要讲述如何实现进程管理的功能, 以下所有的示例代码和实现功能均在 Core/process_manage.py中
示例代码
def kill_process(self, pid):
"""关闭进程"""
try:
if self.get_process_info(pid)['state'] == 'Z': # zombie process
raise ZombieProcess(pid)
os.kill(int(pid), signal.SIGKILL)
except OSError as e:
if e.args[0] == 1: # Operation not permitted
raise AccessDenied(pid)
if e.args[0] == 3: # No such process
raise NoSuchProcess(pid)
关闭该与该进程相关的所有进程
示例代码
def kill_all_process(self, pid, kill_child=True, kill_process_gourp=True):
"""关闭进程 (pid所指进程, 该进程的子进程, 该进程的同组进程)"""
# 获取需要关闭的进程
self_pid = os.getpid()
need_killed_process = [pid]
if kill_child:
need_killed_process.extend(self.get_all_child_process(pid))
if kill_process_gourp and self.get_process_group_id(pid) != self.get_process_group_id(self_pid):
need_killed_process.extend(self.get_same_group_process(self.get_process_group_id(pid)))
need_killed_process = sorted(list(set(need_killed_process)), reverse=True)
# 去掉监控进程本身 (因为启动进程会将启动的进程变成监控进程的子进程,这地方逻辑不是很清晰 todo:更好的进程关闭方式? )
if self_pid in need_killed_process:
need_killed_process.remove(self_pid)
# 逐一关闭
try:
for p in need_killed_process:
self.kill_process(p)
except NoSuchProcess as e:
pass
return True
创建ssh链接demo
def remote_host_client(host, user, password, port):
"""连接远程客户端"""
client = paramiko.SSHClient() # 创建客户端
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(hostname=host, port=port, username=user, password=password, timeout=3)
except Exception as err:
ssh_log.warning("连接远程主机 " + user + " @ " + host + "出现问题 : " + str(err))
print "连接远程主机 " + user + " @ " + host + "出现问题 : " + str(err)
client.close()
return None
return client
关闭进程
def kill_process(host, user, password, port, pid=None, process_name=None):
"""关闭进程"""
res = {"status": "OK", "kill_pid": pid, "kill_process_name": process_name, "result": "",
"comm": "kill -9 {pid}".format(pid=pid),
"stdout": None, "stderr": None, }
client = remote_host_client(host, user, password, port)
if client and pid:
try:
stdin, stdout, stderr = client.exec_command(res["comm"])
res["stdout"] = stdout.read()
res["stderr"] = stderr.read()
except Exception as err:
res["status"] = "execute_error"
res["error"] = str(err)
client.close()
return res
else:
res["status"] = "connect_error"
return res
def start_process(self, execute_file_full_path):
"""后台创建一个新的进程(不随主进程退出,返回创建的进程号)"""
# reference : https://stackoverflow.com/questions/1605520/how-to-launch-and-run-external-script-in-background
# reference : https://www.cnblogs.com/zhoug2020/p/5079407.html
# reference : https://stackoverflow.com/questions/89228/calling-an-external-command-in-python/92395#92395
# reference : https://stackoverflow.com/questions/1196074/how-to-start-a-background-process-in-python
# 获取执行文件相关地址
cwd = execute_file_full_path[:execute_file_full_path.rindex("/")]
execute_file = execute_file_full_path[execute_file_full_path.rindex("/") + 1:]
# 启动进程
if execute_file.endswith('.py'): # python
p = subprocess.Popen(["nohup", "python", execute_file_full_path],
cwd=cwd,
close_fds=True,
stderr=subprocess.STDOUT)
return p.pid
# todo : support more execute file
else:
return False
def start_process(host, user, password, port, process_path=None, start_cmd=None):
"""远程执行命令,获取结果"""
res = {"status": "OK", "process_path": process_path, "start_cmd": start_cmd}
client = remote_host_client(host, user, password, port)
if client:
try:
chan = client.invoke_shell()
chan.send('cd {path}; {sc} \n'.format(path=process_path, sc=start_cmd))
chan.recv(4096)
time.sleep(1.3)
except Exception as err:
res["status"] = "execute_error"
res["error"] = str(err)
client.close()
return res
else:
res["status"] = "connect_error"
return res
很简单, 重启 = 关闭 + 启动
如果有任何问题, 请联系邮箱 h.j.13.new@gmail.com