之前尝试过用python的线程去做监视,发现效果不好,尤其在linux中出现僵尸进程更是不好。
于是考虑直接用linux的shell写一个.sh的脚本,直接去监视python的进程
目录
进程名称修改
linux监视脚本
linux进程退出信号处理函数(僵尸进程)
定时重启
注意事项
进程名称修改
安装修改进程名称的包
pip install setproctitle
这个包,直接就能改进程名称,我只需要把一个任务的所有进程名称都改成这个,所以直接在main主函数入口设置就行了
if __name__ == "__main__":
setproctitle.setproctitle('name')
这样就行
linux监视脚本
写linxu监视脚本
#!/bin/sh
echo "running the program"
echo "running the program" >> /写入log路径/outlog/run.log 2>&1 &
gnome-terminal -t "monitor" -- bash -c "
/执行下一个脚本路径/run_monitor.sh;"
第一个run脚本,先把运行信息打到log里 >>两个箭头是续写 2>&1 & 是输出重定向,使得结果不在终端打出
然后在脚本中开启另一个终端,命名monitor 后面是路径。如果需要打开的终端执行之后不退出,只需在 ; 号后面加上 exec bash即可。
#!/bin/sh
sleep 3
name=co
num=$(ps -ef | pgrep co | wc -l)
echo "The Time is `date +%F-%T`" >> log写入路径/outlog/run.log 2>&1 &
echo "The Time is `date +%F-%T`"
if [ $num -eq 7 ];then
echo "The Time is `date +%F-%T`" >> log写入路径/outlog/run.log 2>&1 &
echo "The Time is `date +%F-%T`"
echo "$name running"
echo "$name running" >> log写入路径/outlog/run.log 2>&1 &
else
echo "The Time is `date +%F-%T`" >> log写入路径/outlog/run.log 2>&1 &
echo "The Time is `date +%F-%T`"
echo "$name is not running"
echo "$name is not running" >> log写入路径/outlog/run.log 2>&1 &
killall $name > log写入路径/outlog/run.log 2>&1 &
gnome-terminal -t "_combination_" -- bash -c "下一个脚本执行路径/runfo.sh;"
sleep 10
fi
while true
do
num=$(ps -ef | pgrep co | wc -l)
sleep 60
if [ $num -eq 7 ];then
echo "$name running"
echo "$name running" >> log写入路径/outlog/run.log 2>&1 &
echo "The Time is `date +%F-%T`" >> log写入路径/outlog/run.log 2>&1 &
echo "The Time is `date +%F-%T`"
else
echo "The Time is `date +%F-%T`" >> log写入路径/outlog/run.log 2>&1 &
echo "The Time is `date +%F-%T`"
echo "$name is not running"
echo "$name is not running" >> log写入路径/outlog/run.log 2>&1 &
killall $name >> log写入路径/outlog/run.log 2>&1 &
echo "kill program finished, read to restart in 3 seconds"
echo "kill program finished, read to restart in 3 seconds" >> log写入路径/run.log 2>&1 &
sleep 3
gnome-terminal -t "combination" -- bash -c "log写入路径/runfo.sh;"
sleep 3
fi
done
监视脚本的思路非常简单, 通过查询有多少个进程名来判断程序是否还在正常运行。这也是我们需要修改进程名称的原因。如果进程数量和我们开启的一样,就继续,不一样就杀掉所有进程,然后再重新开一个终端,再运行
#!/bin/sh
name=co
__conda_setup="$('/home/user/anaconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ];then
eval "$__conda_setup"
else
if [ -f "/home/user/anaconda3/etc/profile.d/conda.sh" ];then
. "/home/user/anaconda3/etc/profile.d/conda.sh"
else
export PATH="/home/inspur/anaconda3/bin:$PATH"
fi
fi
unset __conda_setup
conda activate cm
chmod 755 执行文件路径.py
$nohup python 执行文件路径.py
在shell里进入conda环境,然后执行python脚本,就可以了。
linux进程退出信号处理函数(僵尸进程)
因为我们在python里开启进程的方式不是fork两次的方式,因此我们在python里面杀死进程会产生僵尸进程,所以需要加上信号处理函数
def wait_child(signum, frame):
try:
while True:
global pid_list
time.sleep(0.01)
for i in pid_list:
childpid, status = os.waitpid(i, os.WNOHANG)
if childpid == 0:
continue
exitcode = status >> 8
print('子进程 %s 退出,状态码是 exitcode %s' % (childpid, exitcode))
except OSError as e:
time.sleep(2)
if e.errno == errno.ECHILD:
print("没有需要等待wait的子进程")
else:
raise
在程序的主进程主线程里直接调用
signal.signal(signal.SIGCHLD, wait_child)
要注意pid_list是我开启的进程,就是我需要监视的进程。如果改成-1的话类似os.system() sp.popen()这样通过开启子进程方式运行cmd命令的方法退出时也会触发信号处理函数。
定时重启
linux的定时重启在18.04中直接在ubuntu的桌面版设置就行了,我之前写了rc.local的脚本吗,直接开不了机了我去,还要进安全模式去删除,其实是可以直接设置的。
#!/bin/sh
killall co > log路径/outlog/run.log 2>&1 &
echo "restart" >> log路径/outlog/run.log 2>&1 &
echo "The Time is `date +%F-%T`" >> log路径/outlog/run.log 2>&1 &
echo "The Time is `date +%F-%T`"
echo "restart"
重启脚本先写好
在终端输入
crontab -e
弹出来一个界面,直接可以编辑
我设置的是每周五晚上重启,这个只能说是定时启动一个脚本,那么你就要把重启脚本准备好,具体咋写还是百度把,看看就会了。
注意事项
我设置开机自启时候
就在这个里面,我要开7个差不多的程序,这个只让我设置一个,于是我就写了一个批量启动的脚本,所有启动方式都指向了这个脚本就行了。
如果程序提醒你没有执行权限,那就给文件夹下所有的文件权限
chmod -R 755 文件夹名称
这样就行了