1. ps命令
進程是在你的系統上運行的程序。它們由內核管理,每個進程都有一個與之關聯的ID,稱為進程ID(PID)。這個PID是按照進程創建的順序分配的。
運行ps命令查看正在運行的進程列表:
?
ubuntu@ubuntu:~$?ps ???PID?TTY??????????TIME?CMD ??3309?pts/1????0000?bash ??3794?pts/1????0000?ps ubuntu@ubuntu:~$?
?
PID:進程ID
TTY:控制與進程相關聯的終端
TIME:總CPU使用時間
CMD:可執行/命令的名稱
如果你看一下ps的man手冊,你會發現有很多命令選項可以傳遞,它們會根據你想使用的選項而變化輸出結果。
?
ubuntu@ubuntu:~$?ps?--help?all Usage: ?ps?[options] Basic?options: ?-A,?-e???????????????all?processes ?-a???????????????????all?with?tty,?except?session?leaders ??a???????????????????all?with?tty,?including?other?users ?-d???????????????????all?except?session?leaders ?-N,?--deselect???????negate?selection ??r???????????????????only?running?processes ??T???????????????????all?processes?on?this?terminal ??x???????????????????processes?without?controlling?ttys Selection?by?list: ?-C??????????command?name ?-G,?--Group? ????real?group?id?or?name ?-g,?--group? ??session?or?effective?group?name ?-p,?p,?--pid? ???process?id ????????--ppid? ??parent?process?id ?-q,?q,?--quick-pid? ??????????????????????process?id?(quick?mode) ?-s,?--sid? ??session?id ?-t,?t,?--tty? ???terminal ?-u,?U,?--user? ??effective?user?id?or?name ?-U,?--User? ?????real?user?id?or?name ??The?selection?options?take?as?their?argument?either: ????a?comma-separated?list?e.g.?'-u?root,nobody'?or ????a?blank-separated?list?e.g.?'-p?123?4567' Output?formats: ?-F???????????????????extra?full ?-f???????????????????full-format,?including?command?lines ??f,?--forest?????????ascii?art?process?tree ?-H???????????????????show?process?hierarchy ?-j???????????????????jobs?format ??j???????????????????BSD?job?control?format ?-l???????????????????long?format ??l???????????????????BSD?long?format ?-M,?Z????????????????add?security?data?(for?SELinux) ?-O? ??????????preloaded?with?default?columns ??O? ??????????as?-O,?with?BSD?personality ?-o,?o,?--format? ??????????????????????user-defined?format ??s???????????????????signal?format ??u???????????????????user-oriented?format ??v???????????????????virtual?memory?format ??X???????????????????register?format ?-y???????????????????do?not?show?flags,?show?rss?vs.?addr?(used?with?-l) ?????--context????????display?security?context?(for?SELinux) ?????--headers????????repeat?header?lines,?one?per?page ?????--no-headers?????do?not?print?header?at?all ?????--cols,?--columns,?--width? ??????????????????????set?screen?width ?????--rows,?--lines? ??????????????????????set?screen?height Show?threads: ??H???????????????????as?if?they?were?processes ?-L???????????????????possibly?with?LWP?and?NLWP?columns ?-m,?m????????????????after?processes ?-T???????????????????possibly?with?SPID?column Miscellaneous?options: ?-c???????????????????show?scheduling?class?with?-l?option ??c???????????????????show?true?command?name ??e???????????????????show?the?environment?after?command ??k,????--sort????????specify?sort?order?as:?[+|-]key[,[+|-]key[,...]] ??L???????????????????show?format?specifiers ??n???????????????????display?numeric?uid?and?wchan ??S,????--cumulative??include?some?dead?child?process?data ?-y???????????????????do?not?show?flags,?show?rss?(only?with?-l) ?-V,?V,?--version?????display?version?information?and?exit ?-w,?w????????????????unlimited?output?width ????????--help? ??????????????????????display?help?and?exit For?more?details?see?ps(1).
?
常用的操作命令:
?
ps?aux
?
USER:有效用戶(我們正在使用其訪問權限的用戶)
PID:進程號
%CPU: CPU使用時間除以進程運行時間
%MEM:進程的常駐集大小與機器上物理內存的比率
VSZ:整個進程的虛擬內存使用情況
RSS:常駐集大小,任務使用的非交換物理內存
TTY:控制與進程關聯的終端
STAT:進程狀態碼
START:進程的開始時間
TIME:總CPU使用時間
COMMAND:可執行文件/命令的名稱
另一個非常有用的命令是top命令,top為你提供有關系統上運行的進程的實時信息,而不是快照。默認情況下,你會每10秒刷新一次。top是一個非常有用的工具,可以查看哪些進程占用了大量資源。此處我們對top命令不做過多的講解,想了解的小伙伴可以查看我之前的文章,有對top命令做詳細的講解。
2. 進程的細節
在我們深入了解進程的更多實際應用之前,我們必須了解它是什么以及它是如何工作的。
我們上面說過,進程是系統上正在運行的程序,更準確地說,它是系統分配內存、CPU、I/O以使程序運行的過程。一個進程是一個正在運行的程序的實例,打開3個終端窗口,在兩個窗口中運行cat命令,不傳遞任何選項(cat進程將作為一個進程保持打開狀態,因為它期望stdin)。現在在第三個窗口運行:ps aux | grep cat。將看到cat有兩個進程,盡管它們調用的是同一個程序。
內核負責進程,當我們運行一個程序時,內核將程序的代碼加載到內存中,確定和分配資源,然后監視每個進程:
進程的狀態
進程正在使用和接收的資源
進程所有者
進程信號處理
基本上所有的其他事情
所有進程都在占用資源,內核的工作是確保進程根據自身需求獲得正確數量的資源。當一個進程結束時,它所使用的資源將被釋放給其他進程使用。
3. 進程創建
當創建一個新進程時,現有進程基本上會使用稱為fork系統調用的函數克隆自己。fork系統調用創建了一個基本相同的子進程,這個子進程有一個新的進程ID(PID),原始進程成為它的父進程,并有一個稱為父進程ID PPID的東西。之后,子進程可以繼續使用其父進程之前使用的相同程序,或者更經常地使用execve系統調用來啟動一個新程序。這個系統調用破壞了內核為該進程設置的內存管理,并為新程序設置了新的內存管理。
l選項為我們提供了正在運行的進程的“長格式”甚至更詳細的視圖。你會看到一個標記為PPID的列,這是父ID。現在看看你的終端,你將看到正在運行的進程是你的shell,因此在我的系統上有一個運行bash的進程。現在請記住,當你運行ps l命令時,是從運行bash的進程中運行它的。bash shell的PID是ps l命令的PPID。
當系統啟動時,內核創建了一個名為init的進程,它的PID為1。除非系統關閉,否則無法終止init進程。它以根權限運行,并運行許多保持系統運行的進程。
4. 進程終止
上面我們知道創建進程時會發生什么,那么當我們不再需要它時會發生什么呢?
進程可以使用_exit系統調用退出,這將釋放進程用于重新分配的資源。因此,當一個進程準備終止時,它會用一個叫做終止狀態的東西讓內核知道它為什么要終止。通常情況下,狀態為0表示進程終止成功。然而,這還不足以完全終止一個流程。父進程必須通過使用等待系統調用來確認子進程的終止,這是為了檢查子進程的終止狀態。
孤兒進程當父進程在子進程之前死亡時,內核知道它不會得到一個等待調用,所以它會讓這些進程成為“孤兒”,并將它們置于init(記住所有進程的父進程)的照顧下。init將最終為這些孤兒執行等待系統調用,以便它們可以終止。
僵尸進程當子進程終止而父進程還沒有調用wait時會發生什么? 我們仍然希望能夠看到子進程是如何終止的,因此即使子進程完成了,內核也會將子進程變成僵尸進程。子進程使用的資源仍然被釋放給其他進程使用,但是進程表中仍然有這個僵尸進程的條目。僵尸進程也不能被殺死,因為它們在技術上是“死亡”的,所以你不能使用信號來殺死它們。最終,如果父進程調用等待系統調用,僵尸進程將消失,這被稱為“收割”。如果父進程沒有執行等待調用,init將收養僵尸進程并自動執行等待并移除僵尸進程。僵尸進程太多可能是一件壞事,因為它們會占用進程表上的空間,如果它被填滿,就會阻止其他進程運行。
5. 信號
信號是對進程的通知,告訴它發生了什么事情。
為什么有信號?
它是軟件中斷,有很多用途:
用戶可以輸入一個特殊的終端字符(Ctrl-C)或(Ctrl-Z)來終止、中斷或掛起進程
硬件問題發生時,內核想要通知進程
軟件問題發生時,內核想要通知進程
進程通信的方式
信號處理
當一個信號由某個事件生成時,它被傳遞給一個進程,在傳遞之前它被認為處于掛起狀態。當進程運行時,信號將被傳遞。但是,進程具有信號掩碼,如果指定的話,它們可以將信號傳遞設置為阻塞。當一個信號被傳遞時,進程可以做很多事情:
忽略信號
“捕獲”信號并執行特定的處理程序例程
進程可以終止,而不是正常的退出系統調用
阻塞信號,取決于信號掩碼
常見的信號
每個信號都由具有符號名的整數定義,符號名的形式為SIGxxx。一些最常見的信號是:
SIGHUP或HUP或1:掛機
SIGINT或INT或2:中斷
SIGKILL或KILL或9:殺死
SIGSEGV或SEGV或11:分割錯誤
SIGTERM或TERM或15:軟件終止
SIGSTOP或STOP:停止
數字會隨著信號的變化而變化,所以通常用它們的名字來表示。
有些信號是不可阻擋的,例如SIGKILL信號。KILL信號殺死進程。
6. kill命令
可以發送終止進程的信號,這樣的命令被命名為kill命令。
?
kill?12345
?
12345是要終止的進程的PID。默認情況下,它發送一個TERM信號。SIGTERM信號被發送到進程,進程釋放其資源并保存其狀態來請求終止進程。
還可以使用kill命令指定一個信號:
?
kill?-9?12345
?
這將運行SIGKILL信號并終止進程。
SIGHUP, SIGINT, SIGTERM, SIGKILL, SIGSTOP信號
這些信號看起來都相似,但它們確實有不同之處。
SIGHUP 掛起,當控制終端關閉時發送給進程。例如,如果關閉了一個終端窗口,其中正在運行一個進程,那么將得到一個SIGHUP信號。
SIGINT 是一個中斷信號,因此可以使用Ctrl-C,系統將嘗試優雅地終止進程
SIGTERM 終止進程,但允許它先做一些清理工作
SIGKILL 殺死進程,不做任何清理
SIGSTOP 停止/掛起進程
7. 進程優先級
當你在電腦上同時運行多個程序時,比如Chrome、Microsoft Word或Photoshop,看起來這些進程是同時運行的,但事實并非如此。
進程使用CPU的時間,稱為時間片。然后它們暫停幾毫秒,另一個進程得到一點時間切片。默認情況下,進程調度以這種循環方式進行。每個進程都有足夠的時間片,直到它完成處理。內核處理所有這些進程的切換,并且大多數時候它都做得很好。
進程無法決定何時以及多長時間獲得CPU時間,如果所有進程正常運行,它們將大致獲得相同數量的CPU時間。但是,有一種方法可以用一個不錯的值來影響內核的進程調度算法。優先級它的意思是進程有一個數字來確定它們對CPU的優先級。數值高意味著進程很好,對CPU的優先級較低,數值低或為負數意味著進程不是很好,它想要盡可能多地獲得CPU。
要更改進程優先級別,可以使用nice和renice命令:
?
nice?-n?5?apt?upgrade renice?10?-p?3245
?
nice命令用于設置新進程的優先級。renice命令用于設置已存在進程的優先級。
8. 進程狀態
我們再來看一下:ps aux命令
在STAT列中,看到許多值。linux進程可以處于許多不同的狀態。你將看到的最常見的如下所示:
R: running或runnable,它只是在等待CPU處理它
S:可中斷休眠,等待一個事件完成,例如來自終端的輸入
D:不間斷睡眠,不能被信號殺死或中斷的進程,通常要讓它們消失,你必須重新啟動或修復問題
Z:僵尸進程,僵尸是正在等待收集其狀態的終止進程
T: Stopped,已掛起/停止的進程
9. /proc文件系統
在Linux中一切皆文件,包括進程。進程信息存儲在一個稱為/proc文件系統的特殊文件系統中。
這里看到多個值,每個PID都有子目錄。如果查看ps輸出中的PID,則可以在/proc目錄中找到它。
進入其中一個進程并查看該文件:
你能看到進程狀態信息以及更詳細的信息。/proc目錄是內核查看系統的方式,因此這里有比ps中更多的信息。
10. Job控制
假設你正在一個終端窗口上工作,并且正在運行一個命令,該命令將花費很長時間。在它完成之前,你不能與shell交互,但是我們希望繼續在我們的機器上工作,因此我們需要打開shell。我們可以控制我們的進程如何運行:
將工作發送到后臺
在命令后添加&號將在后臺運行該命令:
?
sleep?1000?& sleep?1001?& sleep?1002?&
?
查看后臺進程
將進程從后臺移動到前臺
要將進程移出后臺,只需指定所需的進程ID。如果不帶任何選項地運行fg,它將帶回最近的后臺進程。
審核編輯:湯梓紅
評論
查看更多