Linux中的ps命令是Process Status的縮寫。ps命令用來列出系統中當前運行的那些進程。ps命令列出的是當前那些進程的快照,就是執行ps命令的那個時刻的那些進程,若是想要動態的顯示進程信息,就可使用top命令。linux
要對進程進行監測和控制,首先必需要了解當前進程的狀況,也就是須要查看當前進程,而 ps 命令就是最基本同時也是很是強大的進程查看命令。使用該命令能夠肯定有哪些進程正在運行和運行的狀態、進程是否結束、進程有沒有僵死、哪些進程佔用了過多的資源等等。總之大部分信息都是能夠經過執行該命令獲得的。nginx
ps 爲咱們提供了進程的一次性的查看,它所提供的查看結果並不動態連續的;若是想對進程時間監控,應該用 top 工具。sql
kill 命令用於殺死進程。shell
ps [參數]
用於顯示當前進程 (process) 的狀態。
ps 的參數很是多, 在此僅列出幾個經常使用的參數並大略介紹含義bash
參數 | 描述 |
---|---|
-A | 列出全部的行程 |
-e | 等於「-A」 |
-a | 顯示現行終端機下的全部進程,包括其餘用戶的進程; |
-u | 以用戶爲主的進程狀態 ; |
x | 一般與 a 這個參數一塊兒使用,可列出較完整信息。 |
-w | 顯示加寬能夠顯示較多的資訊 |
-au | 顯示較詳細的資訊 |
-aux | 顯示全部包含其餘使用者的行程 |
-f | 作一個更爲完整的輸出。 |
命令:網絡
ps -A
輸出:session
[root@localhost autoAweme]# ps -A PID TTY TIME CMD 1 ? 00:00:15 systemd 2 ? 00:00:00 kthreadd 3 ? 00:00:56 ksoftirqd/0 5 ? 00:00:00 kworker/0:0H 7 ? 00:01:01 migration/0 8 ? 00:00:00 rcu_bh 9 ? 00:18:57 rcu_sched 10 ? 00:00:00 lru-add-drain 11 ? 00:00:03 watchdog/0 12 ? 00:00:02 watchdog/1 13 ? 00:01:01 migration/1 14 ? 00:00:56 ksoftirqd/1 16 ? 00:00:00 kworker/1:0H ……省略部分結果
命令:多線程
ps -u root
輸出:less
[root@localhost autoAweme]# ps -u root PID TTY TIME CMD 1 ? 00:00:15 systemd 2 ? 00:00:00 kthreadd 3 ? 00:00:56 ksoftirqd/0 5 ? 00:00:00 kworker/0:0H 7 ? 00:01:01 migration/0 8 ? 00:00:00 rcu_bh 9 ? 00:18:57 rcu_sched 10 ? 00:00:00 lru-add-drain 11 ? 00:00:03 watchdog/0 12 ? 00:00:02 watchdog/1 13 ? 00:01:01 migration/1 14 ? 00:00:56 ksoftirqd/1 16 ? 00:00:00 kworker/1:0H 18 ? 00:00:00 kdevtmpfs 19 ? 00:00:00 netns 20 ? 00:00:00 khungtaskd ……省略部分結果
說明:
顯示root進程用戶信息
命令:
ps -ef
輸出:
[root@localhost autoAweme]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 11月30 ? 00:00:15 /usr/lib/systemd/systemd --swi root 2 0 0 11月30 ? 00:00:00 [kthreadd] root 3 2 0 11月30 ? 00:00:56 [ksoftirqd/0] root 5 2 0 11月30 ? 00:00:00 [kworker/0:0H] root 7 2 0 11月30 ? 00:01:01 [migration/0] ……省略部分結果
命令:
ps -ef|grep uwsgi
輸出:
[root@localhost autoAweme]# ps -ef|grep uwsgi root 30568 795 0 12月01 ? 00:00:19 /home/hc/project/envs/pgc/bin/uwsgi --ini /home/hc/project/pgc.ini root 30578 30568 0 12月01 ? 00:00:00 /home/hc/project/envs/pgc/bin/uwsgi --ini /home/hc/project/pgc.ini root 66069 795 1 12:07 ? 00:04:29 /home/hc/project/envs/autoAweme/bin/uwsgi --ini /home/hc/project/autoAweme.ini root 66096 66069 0 12:07 ? 00:00:01 /home/hc/project/envs/autoAweme/bin/uwsgi --ini /home/hc/project/autoAweme.ini root 80022 86053 0 16:06 pts/1 00:00:00 grep --color=auto uwsgi
命令:
ps -l
輸出:
[root@localhost autoAweme]# ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 S 0 85984 80319 0 80 0 - 58596 do_wai pts/1 00:00:00 su 4 S 0 86053 85984 0 80 0 - 29208 do_wai pts/1 00:00:01 bash 0 R 0 107795 86053 0 80 0 - 38300 - pts/1 00:00:00 ps
說明:
各相關信息的意義
標誌 | 意義 |
---|---|
F | 表明這個程序的旗標 (flag), 4 表明使用者爲 super user |
S | 表明這個程序的狀態 (STAT),關於各 STAT 的意義將在內文介紹 |
UID | 程序被該 UID 所擁有 |
PID | 就是這個程序的 ID ! |
PPID | 則是其上級父程序的ID |
C | CPU 使用的資源百分比 |
PRI | 指進程的執行優先權(Priority的簡寫),其值越小越早被執行; |
NI | 這個進程的nice值,其表示進程可被執行的優先級的修正數值。 |
ADDR | 這個是內核函數,指出該程序在內存的那個部分。若是是個 running的程序,通常就是 "-" |
SZ | 使用掉的內存大小 |
WCHAN | 目前這個程序是否正在運做當中,若爲 - 表示正在運做 |
TTY | 登入者的終端機位置 |
TIME | 使用掉的 CPU 時間。 |
CMD | 所下達的指令爲什麼 |
在預設的狀況下, ps 僅會列出與目前所在的 bash shell 有關的 PID 而已,因此, 當我使用 ps -l 的時候,只有三個 PID。
命令:
ps aux
輸出:
[root@localhost autoAweme]# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 125804 4260 ? Ss 11月30 0:15 /usr/lib/systemd/systemd --switched-root --system --deserialize 22 root 2 0.0 0.0 0 0 ? S 11月30 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S 11月30 0:56 [ksoftirqd/0] root 5 0.0 0.0 0 0 ? S< 11月30 0:00 [kworker/0:0H] root 7 0.0 0.0 0 0 ? S 11月30 1:01 [migration/0] root 8 0.0 0.0 0 0 ? S 11月30 0:00 [rcu_bh] root 9 0.3 0.0 0 0 ? S 11月30 19:02 [rcu_sched] ……省略部分結果
說明:
標誌 | 意義 |
---|---|
USER | 該 process 屬於那個使用者帳號的 |
PID | 該 process 的號碼 |
%CPU | 該 process 使用掉的 CPU 資源百分比 |
%MEM | 該 process 所佔用的物理內存百分比 |
VSZ | 該 process 使用掉的虛擬內存量 (Kbytes) |
RSS | 該 process 佔用的固定的內存量 (Kbytes) |
TTY | 該 process 是在那個終端機上面運做,若與終端機無關,則顯示 ?,另外, tty1-tty6 是本機上面的登入者程序,若爲 pts/0 等等的,則表示爲由網絡鏈接進主機的程序。 |
STAT | 該程序目前的狀態 |
START | 該 process 被觸發啓動的時間 |
TIME | 該 process 實際使用 CPU 運做的時間 |
COMMAND | 該程序的實際指令 |
STAT:該程序目前的狀態,主要的狀態有
命令:
ps -axjf
輸出:
[root@localhost autoAweme]# ps -axjf PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 0 2 0 0 ? -1 S 0 0:00 [kthreadd] 2 3 0 0 ? -1 S 0 0:57 \_ [ksoftirqd/0] 2 5 0 0 ? -1 S< 0 0:00 \_ [kworker/0:0H] 2 7 0 0 ? -1 S 0 1:02 \_ [migration/0] ……省略部分結果 1 80310 2416 2416 ? -1 Sl 1000 0:25 /usr/libexec/gnome-terminal-server 80310 80318 2416 2416 ? -1 S 1000 0:00 \_ gnome-pty-helper 80310 80319 80319 80319 pts/1 28727 Ss 1000 0:00 \_ bash 80319 85984 85984 80319 pts/1 28727 S 0 0:00 \_ su 85984 86053 86053 80319 pts/1 28727 S 0 0:01 \_ bash 86053 28727 28727 80319 pts/1 28727 R+ 0 0:00 \_ ps -axjf
pstree命令以樹狀圖顯示進程間的關係(display a tree of processes)。ps命令能夠顯示當前正在運行的那些進程的信息,可是對於它們之間的關係卻顯示得不夠清晰。在Linux系統中,系統調用fork能夠建立子進程,經過子shell也能夠建立子進程,Linux系統中進程之間的關係天生就是一棵樹,樹的根就是進程PID爲1的init進程。
命令:
pstree
輸出:
[root@localhost autoAweme]# pstree systemd─┬─ModemManager───2*[{ModemManager}] ├─NetworkManager───2*[{NetworkManager}] ├─VGAuthService ├─2*[abrt-watch-log] ├─abrtd ├─accounts-daemon───2*[{accounts-daemon}] ├─alsactl ├─at-spi-bus-laun─┬─dbus-daemon │ └─3*[{at-spi-bus-laun}] ├─at-spi2-registr───2*[{at-spi2-registr}] ├─atd ├─auditd─┬─audispd─┬─sedispatch │ │ └─{audispd} │ └─{auditd} ├─avahi-daemon───avahi-daemon ……省略部分結果
命令:
pstree -p
輸出:
[root@localhost autoAweme]# pstree -p systemd(1)─┬─ModemManager(686)─┬─{ModemManager}(722) │ └─{ModemManager}(744) ├─NetworkManager(796)─┬─{NetworkManager}(807) │ └─{NetworkManager}(811) ├─VGAuthService(677) ├─abrt-watch-log(698) ├─abrt-watch-log(703) ├─abrtd(684) ├─accounts-daemon(680)─┬─{accounts-daemon}(699) │ └─{accounts-daemon}(742) ├─alsactl(679) ├─at-spi-bus-laun(2636)─┬─dbus-daemon(2641) │ ├─{at-spi-bus-laun}(2637) │ ├─{at-spi-bus-laun}(2638) │ └─{at-spi-bus-laun}(2640) ├─at-spi2-registr(2643)─┬─{at-spi2-registr}(2648) │ └─{at-spi2-registr}(2649) ├─atd(1171) ……省略部分結果
命令:
pstree [-p] <pid>
輸出:
root@localhost autoAweme]# pstree 1244 mysqld_safe───mysqld───19*[{mysqld}] [root@localhost autoAweme]# pstree -p 1244 mysqld_safe(1244)───mysqld(1869)─┬─{mysqld}(1906) ├─{mysqld}(1911) ├─{mysqld}(1912) ├─{mysqld}(1913) ├─{mysqld}(1914) ├─{mysqld}(1915) ├─{mysqld}(1916) ├─{mysqld}(1917) ├─{mysqld}(1918) ├─{mysqld}(1919) ├─{mysqld}(1920) ├─{mysqld}(1926) ├─{mysqld}(1927) ├─{mysqld}(1928) ├─{mysqld}(1929) ├─{mysqld}(1930) ├─{mysqld}(1931) ├─{mysqld}(2081) └─{mysqld}(77714)
以樹狀圖顯示進程,相同名稱的進程不合並顯示,而且會顯示命令行參數,若是有-p參數則同時顯示每一個進程的PID。
命令:
pstree -a
輸出:
[root@localhost autoAweme]# pstree -a systemd --switched-root --system --deserialize 22 ├─ModemManager │ └─2*[{ModemManager}] ├─NetworkManager --no-daemon │ └─2*[{NetworkManager}] ├─VGAuthService -s ├─supervisord /usr/bin/supervisord -c /etc/supervisord.conf │ ├─celery /home/hc/project//envs/autoAweme/bin/celery worker -A celery_worker.celery -l info │ │ ├─celery /home/hc/project//envs/autoAweme/bin/celery worker -A celery_worker.celery -l info │ │ │ └─{celery} │ │ ├─celery /home/hc/project//envs/autoAweme/bin/celery worker -A celery_worker.celery -l info │ │ │ └─{celery} │ │ └─2*[{celery}] │ ├─uwsgi --ini /home/hc/project/pgc.ini │ │ └─uwsgi --ini /home/hc/project/pgc.ini │ └─uwsgi --ini /home/hc/project/autoAweme.ini │ ├─uwsgi --ini /home/hc/project/autoAweme.ini │ └─2*[{uwsgi}] ……省略部分結果
注:由於pstree輸出的信息可能比較多,因此最好與more/less配合使用,使用上下箭頭查看,按q退出。
pstree -p | less
命令:
ps -aux |more
命令:
ps -aux > ps001.txt
命令:
ps -o pid,ppid,pgrp,session,tpgid,comm
下面內容來源於 https://blog.csdn.net/zy512638348/article/details/78193278
只有在該狀態的進程纔可能在CPU上運行,同一時刻可能有多個進程處於可執行狀態,這些進程的task_struct結構(進程控制塊)被放入對應的CPU的可執行隊列中(一個進程最多隻能出如今一個CPU的可執行隊列中)。進程調度器的任務就是從各個CPU的可執行隊列中分別選擇一個進程在該CPU上運行。
通常將正在CPU上執行的進程定義爲RUNNING狀態,而將可執行可是還沒有被調度執行的進程定義爲READY狀態,這兩種狀態在linux下同一爲TASK_RUNNING狀態。只要可執行隊列不爲空,其對應的CPU就不能偷懶,就要執行其中某個進程。通常稱此時的CPU「忙碌」。對應的,CPU「空閒」就是指其對應的可執行隊列爲空,以至於CPU無事可作。
處於這個狀態的進程由於等待某個事件的發生(好比等待socket鏈接、等待信號量),而被掛起。這些進程的task_struct結構被放入對應事件的等待隊列中。當這些事件發生時(由外部中斷觸發、或由其餘進程觸發),對應的等待隊列中的一個或多個進程被喚醒。經過ps命令咱們會看到,通常狀況下,進程列表中的絕大多數進程都處於TASK_INTERRUPTIBLE狀態(除非機器的負載很高)。畢竟CPU就那麼幾個,而進程動輒幾十上百個,若是不是絕大多數進程都在睡眠,CPU又怎麼響應的過來。
與TASK_INTERRUPTIBLE狀態相似,進程也處於睡眠狀態,可是此刻的進程是不可中斷的。不可中斷,指的並非CPU不響應外部硬件的中斷,而是指進程不響應異步信號。絕大多數狀況下,進程處在睡眠狀態時,老是應該可以響應異步信號的。不然你將驚奇的發現,kill -9居然殺不死一個正在睡眠的進程了!因而咱們也很好理解,爲何ps命令看到的進程幾乎不會出現TASK_UNINTERRUPTIBLE狀態,而老是TASK_INTERRUPTIBLE狀態。
而TASK_UNINTERRUPTIBLE狀態存在的意義就在於,內核的某些處理流程是不能被打斷的。若是響應異步信號,程序的執行流程中就會被插入一段用於處理異步信號的流程(這個插入流程可能只存在於內核態,也可能延伸到用戶態),因而原有的流程被中斷了。(參見《linux內核異步中斷淺析》)在進程對某些硬件進行操做時(好比進程調用read系統調用對某個設備文件進行讀操做,而read系統調用最終執行到對應設備驅動的代碼,並與對應的物理設備進行交互),可能須要使用TASK_UNINTERRUPTIBLE狀態對進程進行保護,以免進程與設備交互的過程被打斷,形成設備陷入不可控的狀態。這種狀況下的TASK_UNINTERRUPTIBLE狀態老是很是短暫的,經過ps命令基本上不可能捕捉到。
向進程發送一個SIGSTOP信號,它就會因響應信號而進入TASK_STOPPED狀態(除非該進程自己處於TASK_UNINTERRUPTIBLE狀態而不響應信號)。(SIGSTOP與SIGKILL信號同樣,是非強制的。不容許用戶進程經過signal系統的系統調用從新設置對應的信號處理函數)向進程發送一個SIGCONT信號,可讓其從TASK_STOPPED狀態恢復到TASK_RUNNING狀態。
當進程正在被跟蹤時,它處於TASK_TRACED這個特殊的狀態。「正在被跟蹤」指的是進程暫停下來,等待跟蹤它的進程對它進行操做。好比在gdb中對被跟蹤的進程下一個斷點,進程在斷點處停下來的時候就處於TASK_TRACED狀態。而在其餘時候,被跟蹤的進程仍是處於前面提到的那些狀態。
對於進程自己來講,TASK_STOPPED和TASK_TRACED狀態很相似,都是表示進程暫停下來。而TASK_TRACED狀態至關於在TASK_STOPPED之上多了一層保護,處於TASK_TRACED狀態的進程不能響應SIGCONT信號而被喚醒。只能等到調試進程經過ptrace系統調用執行PTRACE_CONT、PTRACE_DETACH等操做(經過ptrace系統調用的參數指定操做),或調試進程退出,被調試的進程才能恢復TASK_RUNNING狀態。
向進程發送一個SIGSTOP信號,它就會因響應信號而進入TASK_STOPPED狀態(除非該進程自己處於TASK_UNINTERRUPTIBLE狀態而不響應信號)。(SIGSTOP與SIGKILL信號同樣,是非強制的。不容許用戶進程經過signal系統的系統調用從新設置對應的信號處理函數)向進程發送一個SIGCONT信號,可讓其從TASK_STOPPED狀態恢復到TASK_RUNNING狀態。
當進程正在被跟蹤時,它處於TASK_TRACED這個特殊的狀態。「正在被跟蹤」指的是進程暫停下來,等待跟蹤它的進程對它進行操做。好比在gdb中對被跟蹤的進程下一個斷點,進程在斷點處停下來的時候就處於TASK_TRACED狀態。而在其餘時候,被跟蹤的進程仍是處於前面提到的那些狀態。
對於進程自己來講,TASK_STOPPED和TASK_TRACED狀態很相似,都是表示進程暫停下來。而TASK_TRACED狀態至關於在TASK_STOPPED之上多了一層保護,處於TASK_TRACED狀態的進程不能響應SIGCONT信號而被喚醒。只能等到調試進程經過ptrace系統調用執行PTRACE_CONT、PTRACE_DETACH等操做(經過ptrace系統調用的參數指定操做),或調試進程退出,被調試的進程才能恢復TASK_RUNNING狀態。
而進程在退出過程當中也可能不會保留它的task_struct。好比這個進程是多線程程序中被detach過的進程(進程?線程?參見《linux線程淺析》)。或者父進程經過設置SIGCHLD信號的handler爲SIG_IGN,顯式的忽略了SIGCHLD信號。(這是posix的規定,儘管子進程的退出信號能夠被設置爲SIGCHLD之外的其餘信號。)此時,進程將被置於EXIT_DEAD退出狀態,這意味着接下來的代碼當即就會將該進程完全釋放。因此EXIT_DEAD狀態是很是短暫的,幾乎不可能經過ps命令捕捉到。
進程是經過fork系列的系統調用(fork、clone、vfork)來建立的,內核(或內核模塊)也能夠經過kernel_thread函數建立內核進程。這些建立子進程的函數本質上都完成了相同的功能——將調用進程複製一份,獲得子進程。(能夠經過選項參數來決定各類資源是共享、仍是私有。)那麼既然調用進程處於TASK_RUNNING狀態(不然,它若不是正在運行,又怎麼進行調用?),則子進程默認也處於TASK_RUNNING狀態。另外,在系統調用調用clone和內核函數kernel_thread也接受CLONE_STOPPED選項,從而將子進程的初始狀態置爲 TASK_STOPPED。
進程自建立之後,狀態可能發生一系列的變化,直到進程退出。而儘管進程狀態有好幾種,可是進程狀態的變遷卻只有兩個方向——從TASK_RUNNING狀態變爲非TASK_RUNNING狀態、或者從非TASK_RUNNING狀態變爲TASK_RUNNING狀態。也就是說,若是給一個TASK_INTERRUPTIBLE狀態的進程發送SIGKILL信號,這個進程將先被喚醒(進入TASK_RUNNING狀態),而後再響應SIGKILL信號而退出(變爲TASK_DEAD狀態)。並不會從TASK_INTERRUPTIBLE狀態直接退出(至少發送一個SIGCHLD信號須要活着吧)。
進程從非TASK_RUNNING狀態變爲TASK_RUNNING狀態,是由別的進程(也多是中斷處理程序)執行喚醒操做來實現的。執行喚醒的進程設置被喚醒進程的狀態爲TASK_RUNNING,而後將其task_struct結構加入到某個CPU的可執行隊列中。因而被喚醒的進程將有機會被調度執行。
而進程從TASK_RUNNING狀態變爲非TASK_RUNNING狀態,則有兩種途徑:一、響應信號而進入TASK_STOPED狀態、或TASK_DEAD狀態;二、執行系統調用主動進入TASK_INTERRUPTIBLE狀態(如nanosleep系統調用)、或TASK_DEAD狀態(如exit系統調用);或因爲執行系統調用須要的資源得不到知足,而進入TASK_INTERRUPTIBLE狀態或TASK_UNINTERRUPTIBLE狀態(如select系統調用)。顯然,這兩種狀況都只能發生在進程正在CPU上執行的狀況下。