ps命令
top命令
free命令
kill命令
ps
ps是Linux 中最基础的浏览系统中的进程的命令。能列出系统中运行的进程,包括进程号、命令、CPU使用量、内存使用量等。接下来解读一下Linux操作系统的进程和Windows「Ctrl+Alt+delete」直接的差异。
在进行了解进程命令之前需要知道进程的一些状态
Linux上进程有5种状态:
- 运行(正在运行或在运行队列中等待)
- 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号)
- 不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生)
- 僵死(进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放)
- 停止(进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行)
ps工具标识进程的5种状态码:
- D 不可中断 uninterruptible sleep
- R 运行 runnable
- S 中断 sleeping
- T 停止 traced or stopped
- Z 僵死 a defunct (”zombie”) process
Linux操作系统进程执行的状态转换图如图所示:
下面来看一下ps命令
ps --help命令可以查看ps命令的使用说明
root@xiaozhou:~# ps --help
Usage:
ps [options]
Try 'ps --help <simple|list|output|threads|misc|all>'
or 'ps --help <s|l|o|t|m|a>'
for additional help text.
For more details see ps(1).
或者使用man ps命令
查询ps的详细说明
在man手册
关于ps的解读中,总结了一下几个参数的含义:
- ps a 显示现行终端机下的所有程序,包括其他用户的程序。
- ps -A 显示所有程序。
- ps c 列出程序时,显示每个程序真正的指令名称,而不包含路径,参数或常驻服务的标示。
- ps -e 此参数的效果和指定"A"参数相同。
- ps e 列出程序时,显示每个程序所使用的环境变量。
- ps f 用ASCII字符显示树状结构,表达程序间的相互关系。
- ps -H 显示树状结构,表示程序间的相互关系。
- ps -N 显示所有的程序,除了执行ps指令终端机下的程序之外。
- ps s 采用程序信号的格式显示程序状况。
- ps S 列出程序时,包括已中断的子程序资料。
- ps -t <终端机编号> 指定终端机编号,并列出属于该终端机的程序的状况。
- ps u 以用户为主的格式来显示程序状况。
- ps x 显示所有程序,不以终端机来区分。
- ps -l 较详细的显示该PID的信息
以上的参数是可以拼接使用的,那就了解一些常用的参数组合ps aux命令
root@xiaozhou:~# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.6 168376 12428 ? Ss Oct30 0:05 /sbin/init noibrs
root 2 0.0 0.0 0 0 ? S Oct30 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< Oct30 0:00 [rcu_gp]
root 4 0.0 0.0 0 0 ? I< Oct30 0:00 [rcu_par_gp]
root 6 0.0 0.0 0 0 ? I< Oct30 0:00 [kworker/0:0H-kblockd]
ps -ef命令
root@xiaozhou:~# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Oct30 ? 00:00:05 /sbin/init noibrs
root 2 0 0 Oct30 ? 00:00:00 [kthreadd]
root 3 2 0 Oct30 ? 00:00:00 [rcu_gp]
root 4 2 0 Oct30 ? 00:00:00 [rcu_par_gp]
root 6 2 0 Oct30 ? 00:00:00 [kworker/0:0H-kblockd]
查看进程状态这两个是命令是最常用的,使用ps aux
可以查看进程的详细运行状态等。使用ps -ef
不仅可以显示自身的PID,也可以显示PPID(父进程)。但是显示不了进程的运行状态
top命令
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器
root@xiaozhou:~# top -help
procps-ng UNKNOWN
Usage:
top -hv | -bcEHiOSs1 -d secs -n max -u|U user -p pid(s) -o field -w [cols]
root@xiaozhou:~#
man手册关于top的解释
root@xiaozhou:~# top
top - 22:37:06 up 6 days, 6 min, 1 user, load average: 0.00, 0.00, 0.00
Tasks: 95 total, 1 running, 94 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.2 us, 0.2 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 1884.3 total, 86.0 free, 572.7 used, 1225.6 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 1139.7 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
745 root 10 -10 112732 19904 14716 S 1.0 1.0 92:51.92 AliYunDun
15964 mysql 20 0 1749720 383656 36776 S 0.7 19.9 0:01.65 mysqld
538 root 20 0 928940 21964 11956 S 0.3 1.1 15:45.87 exe
953 root 10 -10 424024 6076 5592 S 0.3 0.3 3:52.50 AliSecGuard
1 root 20 0 168376 12428 8320 S 0.0 0.6 0:05.80 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.07 kthreadd
关闭进程,重启进程
在上一片文章中linux的目录结构里面说过,在目录/etc/init.d/目录下包含许多系统各种服务的启动和停止脚本。假设进程占用内存较大或者进程异常,我们是重启这个进程restart。如下图所示:
root@xiaozhou:~# ps aux | grep mysql
mysql 15743 0.2 19.8 1749720 383432 ? Ssl 22:13 0:02 /usr/sbin/mysqld
root 15928 0.0 0.0 10760 660 pts/0 S+ 22:27 0:00 grep --color=auto mysql
root@xiaozhou:~#
root@xiaozhou:~# /etc/init.d/mysql restart
Restarting mysql (via systemctl): mysql.service.
root@xiaozhou:~#
root@xiaozhou:~# ps aux | grep mysql
mysql 15964 20.2 19.8 1749720 383652 ? Ssl 22:27 0:00 /usr/sbin/mysqld
root 16015 0.0 0.0 10760 724 pts/0 S+ 22:27 0:00 grep --color=auto mysql
我们重启了mysqld这个进程,可以看出进程号已经改变(从15743到15964),说明进程已经重启。
Linux下有3个特殊的进程,idle进程(PID=0), init进程(PID=1)和kthreadd(PID=2)
- idle进程由系统自动创建,运行在内核态.idle进程其pid=0,其前身是系统创建的第一个进程,也是唯一一个没有通过fork或者kernel_thread产生的进程。完成加载系统后,演变为进程调度、交换.
- init进程由idle通过kernel_thread创建,在内核空间完成初始化后,加载init程序,并最终用户空间创建 .init 进程 (pid = 1, ppid = 0),init进程由0进程创建,完成系统的初始化.是系统中所有其它用户进程的祖先进程.
- kthreadd进程由idle通过kernel_thread创建,并始终运行在内核空间,负责所有内核线程的调度和管理 .kthreadd (pid = 2, ppid = 0)它的任务就是管理和调度其他内核线程kernel_thread,会循环执行一个kthread的函数,该函数的作用就是运行kthread_create_list全局链表中维护的kthread,当我们调用kernel_thread创建的内核线程会被加入到此链表中,因此所有的内核线程都是直接或者间接的以kthreadd为父进程.
我们来看一下进程状态[下面是删减版,进程数量太多,列举一部分]
root@xiaozhou:~# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Oct30 ? 00:00:05 /sbin/init noibrs
root 2 0 0 Oct30 ? 00:00:00 [kthreadd]
root 3 2 0 Oct30 ? 00:00:00 [rcu_gp]
root 4 2 0 Oct30 ? 00:00:00 [rcu_par_gp]
root 6 2 0 Oct30 ? 00:00:00 [kworker/0:0H-kblockd]
root 9 2 0 Oct30 ? 00:00:00 [mm_percpu_wq]
root 10 2 0 Oct30 ? 00:00:00 [ksoftirqd/0]
root 85 2 0 Oct30 ? 00:00:00 [watchdogd]
root 88 2 0 Oct30 ? 00:00:00 [kswapd0]
root 89 2 0 Oct30 ? 00:00:00 [ecryptfs-kthrea]
root 187 2 0 Oct30 ? 00:00:00 [ext4-rsv-conver]
root 232 1 0 Oct30 ? 00:00:02 /lib/systemd/systemd-journald
root 265 1 0 Oct30 ? 00:00:01 /lib/systemd/systemd-udevd
root 299 2 0 Oct30 ? 00:00:00 [cryptd]
root 328 2 0 Oct30 ? 00:00:00 [nfit]
systemd+ 419 1 0 Oct30 ? 00:00:00 /lib/systemd/systemd-networkd
systemd+ 436 1 0 Oct30 ? 00:00:24 /lib/systemd/systemd-resolved
root 450 1 0 Oct30 ? 00:01:33 /usr/local/share/assist-daemon/assist_daemon
root 451 1 0 Oct30 ? 00:00:00 /usr/local/cloudmonitor/CmsGoAgent.linux-amd64
root 452 1 0 Oct30 ? 00:00:08 /usr/lib/accountsservice/accounts-daemon
root 464 1 0 Oct30 ? 00:07:28 /usr/local/share/aliyun-assist/2.2.3.247/aliyun-service
root 535 1 0 Oct30 ? 00:00:00 /usr/bin/python3 /usr/bin/networkd-dispatcher --run-startup-triggers
root 538 451 0 Oct30 ? 00:15:45 CmsGoAgent-Worker start
syslog 551 1 0 Oct30 ? 00:00:00 /usr/sbin/rsyslogd -n -iNONE
root 563 1 0 Oct30 ? 00:00:00 /lib/systemd/systemd-logind
daemon 565 1 0 Oct30 ? 00:00:00 /usr/sbin/atd -f
Debian-+ 584 1 0 Oct30 ? 00:02:26 /usr/sbin/snmpd -LOw -u Debian-snmp -g Debian-snmp -I -smux mteTrigger mteTriggerConf -f -p /run/snmpd.pi
root 585 1 0 Oct30 ? 00:00:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
root 586 1 0 Oct30 ? 00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data 587 586 0 Oct30 ? 00:00:00 nginx: worker process
www-data 588 586 0 Oct30 ? 00:00:00 nginx: worker process
root 631 1 0 Oct30 ttyS0 00:00:00 /sbin/agetty -o -p -- \u --keep-baud 115200,38400,9600 ttyS0 vt220
root 657 1 0 Oct30 tty1 00:00:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
root 15586 585 0 22:08 ? 00:00:00 sshd: root@pts/0
root 15597 1 0 22:08 ? 00:00:00 /lib/systemd/systemd --user
root 15601 15597 0 22:08 ? 00:00:00 (sd-pam)
root 15608 2 0 22:08 ? 00:00:00 [kworker/1:0-events]
root 15896 2 0 22:24 ? 00:00:00 [kworker/0:2-events]
root 15963 2 0 22:27 ? 00:00:00 [kworker/1:2-events]
mysql 15964 1 0 22:27 ? 00:00:01 /usr/sbin/mysqld
root 16016 2 0 22:28 ? 00:00:00 [kworker/u4:1-events_unbound]
root 16054 15644 0 22:31 pts/0 00:00:00 ps -ef
可以看到很多进程的PPID号是1和2。也就是init进程和kthreadd进程。
在使用Windows系统的过程中,都碰到过应用程序卡死的情况。应对此问题,我们一般都是等待失去响应的程序恢复,或者是直接使用任务管理器将其强制关闭,然后再重新打开。
在Linux中,遇到特别耗费资源的进程,当然需要使用top命令
查看进程占用率高的进程。或者使用free -m命令
查看内存剩余。假设需要强杀进程来释放空间。我们涉及到Linux中信号📶的知识,在这里简单的描述一下,信号的详解会在接下来的文章里面叙述。free -m命令查看内存空间
root@xiaozhou:~# free -m
total used free shared buff/cache available
Mem: 1884 593 86 2 1204 1121
Swap: 0 0 0
root@xiaozhou:~#
在linux中存在着64种信号
使用kill -l命令
查看信号列表
root@xiaozhou:~# kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
root@xiaozhou:~#
在前面说过进程会被这些个信号> (进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号强制停止运行)那问题就在于如何发信号给这些个进程。使用kill命令发信号
root@xiaozhou:~#pidof mysqld
15964
root@xiaozhou:~#
root@xiaozhou:~# ps aux | grep mysqld | grep -v grep
mysql 15964 0.1 19.8 1749720 383656 ? Ssl 22:27 0:04 /usr/sbin/mysqld
root@xiaozhou:~# kill -9 15964
root@xiaozhou:~#
root@xiaozhou:~# ps aux | grep mysqld | grep -v grep
mysql 16343 29.6 20.8 1763376 402296 ? Ssl 23:13 0:00 /usr/sbin/mysqld
我们从上面可以看到mysqld进程被重启了
。
关于Linux的这一块进程的知识还有很多,后面的文章跟大家分享僵尸进程,孤儿进程等等知识,以及守护进程(daemon进程).