引言
基础概念
什么是进程?
进程状态
1. 运行态(Running)
正在运行:进程正在使用CPU执行指令。
就绪运行:进程已准备好运行,但由于其他进程正在运行,它正在等待CPU时间。
2. 就绪态(Ready)
进程已从阻塞态变为就绪态,等待被调度运行。
进程完成I/O操作后,等待再次调度。
3. 阻塞态(Blocked)
等待I/O:进程正在等待I/O操作完成,如读取文件或网络通信。
等待资源:进程需要的资源不可用,如等待内存分配或等待其他进程释放锁。
4. 停止态(Stopped)
5. 僵尸态(Zombie)
进程状态的转换
新建:当进程被创建时,它从新建状态开始。
就绪:进程被调度器放入就绪队列,等待被调度。
运行:进程被调度器选中,开始在CPU上执行。
阻塞:进程因为等待某个事件(如I/O)而进入阻塞态。
停止:进程因为接收到停止信号而进入停止态。
终止:进程完成执行或被强制终止。
僵尸:进程终止后,父进程未及时回收其状态,进程进入僵尸态。
进程状态说明
状态 | 说明 |
R | Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中, 正在运行或者正在等待运行 |
D | Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep), 一般表示进程正在跟硬件交互, 并且交互过程不允许被其他进程或中断打断 |
Z | Zombie的缩写,它表示僵尸进程,也就是进程实际上已经结束了, 但是父进程还没有回收它的资源(比如进程的描述符、PID 等) |
S | Interruptible Sleep 的缩写,也就是可中断状态睡眠, 表示进程因为等待某个事件而被系统挂起。 当进程等待的事件发生时,它会被唤醒并进入 R 状态 |
I | Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。 前面说了,硬件交互导致的不可中断进程用 D 表示, 但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。 要注意,D 状态的进程会导致平均负载升高, I 状态的进程却不会 |
T或者 t | Stopped 或 Traced 的缩写,表示进程处于暂停或者跟踪状态。 向一个进程发送 SIGSTOP 信号,它就会因响应这个信号变成暂停状态(Stopped);再向它发送 SIGCONT 信号,进程又会恢复运行(如果进程是终端里直接启动的,则需要你用 fg 命令,恢复到前台运行)。而当你用调试器(如 gdb)调试一个进程时,在使用断点中断进程后,进程就会变成跟踪状态,这其实也是一种特殊的暂停状态,只不过你可以用调试器来跟踪并按需要控制进程的运行 |
X | Dead 的缩写,表示进程已经消亡 |
s | 表示这个进程是一个会话的领导进程 |
+ | 表示前台进程组 |
< | 优先级较高的进程 |
l | 以线程的方式运行 |
基础命令
ps
ps aux
top
top
pidof
pidof nginx
kill
kill -9 PID
进程控制
后台运行
sleep 100 &
进程组
信号
高级技巧
进程监控
进程限制
ulimit -u 100
进程优先级
nice -n 10 long_running_task
守护进程
nohup long_running_task &
进程管理脚本
脚本1:监控特定进程是否存在
# 监控特定进程是否存在的脚本
process_name="nginx" # 要监控的进程名
while true; do
if pgrep -x "$process_name" > /dev/null; then
echo "$process_name is running."
else
echo "$process_name is not running. Starting $process_name..."
# 假设nginx的启动命令是service nginx start
service $process_name start
fi
sleep 60 # 每60秒检查一次
done
脚本2:限制特定用户进程数量
# 限制特定用户进程数量的脚本
username="username" # 要限制的用户
max_processes=10 # 最大进程数
while true; do
current_count=$(ps -u $username -o pid= | wc -l)
if [ $current_count -gt $max_processes ]; then
echo "Process limit exceeded. Current: $current_count"
# 杀掉最早的一个进程
oldest_pid=$(ps -u $username -o pid= --sort=start_time | head -n 1)
kill -9 $oldest_pid
echo "Killed process $oldest_pid"
fi
sleep 60 # 每60秒检查一次
done
脚本3:清理僵尸进程
# 清理僵尸进程的脚本
while true; do
# 查找僵尸进程
zombie_pids=$(ps aux | grep 'Z' | awk '{print $2}')
if [ ! -z "$zombie_pids" ]; then
echo "Found zombie processes: $zombie_pids"
# 杀死僵尸进程
kill -9 $zombie_pids
echo "Killed zombie processes."
else
echo "No zombie processes found."
fi
sleep 60 # 每60秒检查一次
done
脚本4:监控并重启崩溃的服务
# 监控并重启崩溃服务的脚本
service_name="httpd" # 要监控的服务名
while true; do
if service $service_name status > /dev/null 2>&1; then
echo "$service_name is running."
else
echo "$service_name has crashed. Restarting..."
# 重启服务
service $service_name restart
fi
sleep 60 # 每60秒检查一次
done
注: 这些脚本需要根据你的具体环境和需求进行调整。例如,启动和监控服务的命令可能因你的系统和配置而异。在实际使用这些脚本之前,请确保你已经测试并验证了它们的功能。同时,对于生产环境,建议使用更健壮的监控和日志记录机制。