1. ps命令
進(jìn)程是在你的系統(tǒng)上運(yùn)行的程序。它們由內(nèi)核管理,每個(gè)進(jìn)程都有一個(gè)與之關(guān)聯(lián)的ID,稱為進(jìn)程ID(PID)。這個(gè)PID是按照進(jìn)程創(chuàng)建的順序分配的。
運(yùn)行ps命令查看正在運(yùn)行的進(jìn)程列表:
?
ubuntu@ubuntu:~$?ps ???PID?TTY??????????TIME?CMD ??3309?pts/1????0000?bash ??3794?pts/1????0000?ps ubuntu@ubuntu:~$?
?
PID:進(jìn)程ID
TTY:控制與進(jìn)程相關(guān)聯(lián)的終端
TIME:總CPU使用時(shí)間
CMD:可執(zhí)行/命令的名稱
如果你看一下ps的man手冊,你會(huì)發(fā)現(xiàn)有很多命令選項(xiàng)可以傳遞,它們會(huì)根據(jù)你想使用的選項(xiàng)而變化輸出結(jié)果。
?
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:有效用戶(我們正在使用其訪問權(quán)限的用戶)
PID:進(jìn)程號(hào)
%CPU: CPU使用時(shí)間除以進(jìn)程運(yùn)行時(shí)間
%MEM:進(jìn)程的常駐集大小與機(jī)器上物理內(nèi)存的比率
VSZ:整個(gè)進(jìn)程的虛擬內(nèi)存使用情況
RSS:常駐集大小,任務(wù)使用的非交換物理內(nèi)存
TTY:控制與進(jìn)程關(guān)聯(lián)的終端
STAT:進(jìn)程狀態(tài)碼
START:進(jìn)程的開始時(shí)間
TIME:總CPU使用時(shí)間
COMMAND:可執(zhí)行文件/命令的名稱
另一個(gè)非常有用的命令是top命令,top為你提供有關(guān)系統(tǒng)上運(yùn)行的進(jìn)程的實(shí)時(shí)信息,而不是快照。默認(rèn)情況下,你會(huì)每10秒刷新一次。top是一個(gè)非常有用的工具,可以查看哪些進(jìn)程占用了大量資源。此處我們對top命令不做過多的講解,想了解的小伙伴可以查看我之前的文章,有對top命令做詳細(xì)的講解。
2. 進(jìn)程的細(xì)節(jié)
在我們深入了解進(jìn)程的更多實(shí)際應(yīng)用之前,我們必須了解它是什么以及它是如何工作的。
我們上面說過,進(jìn)程是系統(tǒng)上正在運(yùn)行的程序,更準(zhǔn)確地說,它是系統(tǒng)分配內(nèi)存、CPU、I/O以使程序運(yùn)行的過程。一個(gè)進(jìn)程是一個(gè)正在運(yùn)行的程序的實(shí)例,打開3個(gè)終端窗口,在兩個(gè)窗口中運(yùn)行cat命令,不傳遞任何選項(xiàng)(cat進(jìn)程將作為一個(gè)進(jìn)程保持打開狀態(tài),因?yàn)樗谕鹲tdin)?,F(xiàn)在在第三個(gè)窗口運(yùn)行:ps aux | grep cat。將看到cat有兩個(gè)進(jìn)程,盡管它們調(diào)用的是同一個(gè)程序。
內(nèi)核負(fù)責(zé)進(jìn)程,當(dāng)我們運(yùn)行一個(gè)程序時(shí),內(nèi)核將程序的代碼加載到內(nèi)存中,確定和分配資源,然后監(jiān)視每個(gè)進(jìn)程:
進(jìn)程的狀態(tài)
進(jìn)程正在使用和接收的資源
進(jìn)程所有者
進(jìn)程信號(hào)處理
基本上所有的其他事情
所有進(jìn)程都在占用資源,內(nèi)核的工作是確保進(jìn)程根據(jù)自身需求獲得正確數(shù)量的資源。當(dāng)一個(gè)進(jìn)程結(jié)束時(shí),它所使用的資源將被釋放給其他進(jìn)程使用。
3. 進(jìn)程創(chuàng)建
當(dāng)創(chuàng)建一個(gè)新進(jìn)程時(shí),現(xiàn)有進(jìn)程基本上會(huì)使用稱為fork系統(tǒng)調(diào)用的函數(shù)克隆自己。fork系統(tǒng)調(diào)用創(chuàng)建了一個(gè)基本相同的子進(jìn)程,這個(gè)子進(jìn)程有一個(gè)新的進(jìn)程ID(PID),原始進(jìn)程成為它的父進(jìn)程,并有一個(gè)稱為父進(jìn)程ID PPID的東西。之后,子進(jìn)程可以繼續(xù)使用其父進(jìn)程之前使用的相同程序,或者更經(jīng)常地使用execve系統(tǒng)調(diào)用來啟動(dòng)一個(gè)新程序。這個(gè)系統(tǒng)調(diào)用破壞了內(nèi)核為該進(jìn)程設(shè)置的內(nèi)存管理,并為新程序設(shè)置了新的內(nèi)存管理。
l選項(xiàng)為我們提供了正在運(yùn)行的進(jìn)程的“長格式”甚至更詳細(xì)的視圖。你會(huì)看到一個(gè)標(biāo)記為PPID的列,這是父ID?,F(xiàn)在看看你的終端,你將看到正在運(yùn)行的進(jìn)程是你的shell,因此在我的系統(tǒng)上有一個(gè)運(yùn)行bash的進(jìn)程。現(xiàn)在請記住,當(dāng)你運(yùn)行ps l命令時(shí),是從運(yùn)行bash的進(jìn)程中運(yùn)行它的。bash shell的PID是ps l命令的PPID。
當(dāng)系統(tǒng)啟動(dòng)時(shí),內(nèi)核創(chuàng)建了一個(gè)名為init的進(jìn)程,它的PID為1。除非系統(tǒng)關(guān)閉,否則無法終止init進(jìn)程。它以根權(quán)限運(yùn)行,并運(yùn)行許多保持系統(tǒng)運(yùn)行的進(jìn)程。
4. 進(jìn)程終止
上面我們知道創(chuàng)建進(jìn)程時(shí)會(huì)發(fā)生什么,那么當(dāng)我們不再需要它時(shí)會(huì)發(fā)生什么呢?
進(jìn)程可以使用_exit系統(tǒng)調(diào)用退出,這將釋放進(jìn)程用于重新分配的資源。因此,當(dāng)一個(gè)進(jìn)程準(zhǔn)備終止時(shí),它會(huì)用一個(gè)叫做終止?fàn)顟B(tài)的東西讓內(nèi)核知道它為什么要終止。通常情況下,狀態(tài)為0表示進(jìn)程終止成功。然而,這還不足以完全終止一個(gè)流程。父進(jìn)程必須通過使用等待系統(tǒng)調(diào)用來確認(rèn)子進(jìn)程的終止,這是為了檢查子進(jìn)程的終止?fàn)顟B(tài)。
孤兒進(jìn)程當(dāng)父進(jìn)程在子進(jìn)程之前死亡時(shí),內(nèi)核知道它不會(huì)得到一個(gè)等待調(diào)用,所以它會(huì)讓這些進(jìn)程成為“孤兒”,并將它們置于init(記住所有進(jìn)程的父進(jìn)程)的照顧下。init將最終為這些孤兒執(zhí)行等待系統(tǒng)調(diào)用,以便它們可以終止。
僵尸進(jìn)程當(dāng)子進(jìn)程終止而父進(jìn)程還沒有調(diào)用wait時(shí)會(huì)發(fā)生什么? 我們?nèi)匀幌M軌蚩吹阶舆M(jìn)程是如何終止的,因此即使子進(jìn)程完成了,內(nèi)核也會(huì)將子進(jìn)程變成僵尸進(jìn)程。子進(jìn)程使用的資源仍然被釋放給其他進(jìn)程使用,但是進(jìn)程表中仍然有這個(gè)僵尸進(jìn)程的條目。僵尸進(jìn)程也不能被殺死,因?yàn)樗鼈冊诩夹g(shù)上是“死亡”的,所以你不能使用信號(hào)來殺死它們。最終,如果父進(jìn)程調(diào)用等待系統(tǒng)調(diào)用,僵尸進(jìn)程將消失,這被稱為“收割”。如果父進(jìn)程沒有執(zhí)行等待調(diào)用,init將收養(yǎng)僵尸進(jìn)程并自動(dòng)執(zhí)行等待并移除僵尸進(jìn)程。僵尸進(jìn)程太多可能是一件壞事,因?yàn)樗鼈儠?huì)占用進(jìn)程表上的空間,如果它被填滿,就會(huì)阻止其他進(jìn)程運(yùn)行。
5. 信號(hào)
信號(hào)是對進(jìn)程的通知,告訴它發(fā)生了什么事情。
為什么有信號(hào)?
它是軟件中斷,有很多用途:
用戶可以輸入一個(gè)特殊的終端字符(Ctrl-C)或(Ctrl-Z)來終止、中斷或掛起進(jìn)程
硬件問題發(fā)生時(shí),內(nèi)核想要通知進(jìn)程
軟件問題發(fā)生時(shí),內(nèi)核想要通知進(jìn)程
進(jìn)程通信的方式
信號(hào)處理
當(dāng)一個(gè)信號(hào)由某個(gè)事件生成時(shí),它被傳遞給一個(gè)進(jìn)程,在傳遞之前它被認(rèn)為處于掛起狀態(tài)。當(dāng)進(jìn)程運(yùn)行時(shí),信號(hào)將被傳遞。但是,進(jìn)程具有信號(hào)掩碼,如果指定的話,它們可以將信號(hào)傳遞設(shè)置為阻塞。當(dāng)一個(gè)信號(hào)被傳遞時(shí),進(jìn)程可以做很多事情:
忽略信號(hào)
“捕獲”信號(hào)并執(zhí)行特定的處理程序例程
進(jìn)程可以終止,而不是正常的退出系統(tǒng)調(diào)用
阻塞信號(hào),取決于信號(hào)掩碼
常見的信號(hào)
每個(gè)信號(hào)都由具有符號(hào)名的整數(shù)定義,符號(hào)名的形式為SIGxxx。一些最常見的信號(hào)是:
SIGHUP或HUP或1:掛機(jī)
SIGINT或INT或2:中斷
SIGKILL或KILL或9:殺死
SIGSEGV或SEGV或11:分割錯(cuò)誤
SIGTERM或TERM或15:軟件終止
SIGSTOP或STOP:停止
數(shù)字會(huì)隨著信號(hào)的變化而變化,所以通常用它們的名字來表示。
有些信號(hào)是不可阻擋的,例如SIGKILL信號(hào)。KILL信號(hào)殺死進(jìn)程。
6. kill命令
可以發(fā)送終止進(jìn)程的信號(hào),這樣的命令被命名為kill命令。
?
kill?12345
?
12345是要終止的進(jìn)程的PID。默認(rèn)情況下,它發(fā)送一個(gè)TERM信號(hào)。SIGTERM信號(hào)被發(fā)送到進(jìn)程,進(jìn)程釋放其資源并保存其狀態(tài)來請求終止進(jìn)程。
還可以使用kill命令指定一個(gè)信號(hào):
?
kill?-9?12345
?
這將運(yùn)行SIGKILL信號(hào)并終止進(jìn)程。
SIGHUP, SIGINT, SIGTERM, SIGKILL, SIGSTOP信號(hào)
這些信號(hào)看起來都相似,但它們確實(shí)有不同之處。
SIGHUP 掛起,當(dāng)控制終端關(guān)閉時(shí)發(fā)送給進(jìn)程。例如,如果關(guān)閉了一個(gè)終端窗口,其中正在運(yùn)行一個(gè)進(jìn)程,那么將得到一個(gè)SIGHUP信號(hào)。
SIGINT 是一個(gè)中斷信號(hào),因此可以使用Ctrl-C,系統(tǒng)將嘗試優(yōu)雅地終止進(jìn)程
SIGTERM 終止進(jìn)程,但允許它先做一些清理工作
SIGKILL 殺死進(jìn)程,不做任何清理
SIGSTOP 停止/掛起進(jìn)程
7. 進(jìn)程優(yōu)先級
當(dāng)你在電腦上同時(shí)運(yùn)行多個(gè)程序時(shí),比如Chrome、Microsoft Word或Photoshop,看起來這些進(jìn)程是同時(shí)運(yùn)行的,但事實(shí)并非如此。
進(jìn)程使用CPU的時(shí)間,稱為時(shí)間片。然后它們暫停幾毫秒,另一個(gè)進(jìn)程得到一點(diǎn)時(shí)間切片。默認(rèn)情況下,進(jìn)程調(diào)度以這種循環(huán)方式進(jìn)行。每個(gè)進(jìn)程都有足夠的時(shí)間片,直到它完成處理。內(nèi)核處理所有這些進(jìn)程的切換,并且大多數(shù)時(shí)候它都做得很好。
進(jìn)程無法決定何時(shí)以及多長時(shí)間獲得CPU時(shí)間,如果所有進(jìn)程正常運(yùn)行,它們將大致獲得相同數(shù)量的CPU時(shí)間。但是,有一種方法可以用一個(gè)不錯(cuò)的值來影響內(nèi)核的進(jìn)程調(diào)度算法。優(yōu)先級它的意思是進(jìn)程有一個(gè)數(shù)字來確定它們對CPU的優(yōu)先級。數(shù)值高意味著進(jìn)程很好,對CPU的優(yōu)先級較低,數(shù)值低或?yàn)樨?fù)數(shù)意味著進(jìn)程不是很好,它想要盡可能多地獲得CPU。
要更改進(jìn)程優(yōu)先級別,可以使用nice和renice命令:
?
nice?-n?5?apt?upgrade renice?10?-p?3245
?
nice命令用于設(shè)置新進(jìn)程的優(yōu)先級。renice命令用于設(shè)置已存在進(jìn)程的優(yōu)先級。
8. 進(jìn)程狀態(tài)
我們再來看一下:ps aux命令
在STAT列中,看到許多值。linux進(jìn)程可以處于許多不同的狀態(tài)。你將看到的最常見的如下所示:
R: running或runnable,它只是在等待CPU處理它
S:可中斷休眠,等待一個(gè)事件完成,例如來自終端的輸入
D:不間斷睡眠,不能被信號(hào)殺死或中斷的進(jìn)程,通常要讓它們消失,你必須重新啟動(dòng)或修復(fù)問題
Z:僵尸進(jìn)程,僵尸是正在等待收集其狀態(tài)的終止進(jìn)程
T: Stopped,已掛起/停止的進(jìn)程
9. /proc文件系統(tǒng)
在Linux中一切皆文件,包括進(jìn)程。進(jìn)程信息存儲(chǔ)在一個(gè)稱為/proc文件系統(tǒng)的特殊文件系統(tǒng)中。
這里看到多個(gè)值,每個(gè)PID都有子目錄。如果查看ps輸出中的PID,則可以在/proc目錄中找到它。
進(jìn)入其中一個(gè)進(jìn)程并查看該文件:
你能看到進(jìn)程狀態(tài)信息以及更詳細(xì)的信息。/proc目錄是內(nèi)核查看系統(tǒng)的方式,因此這里有比ps中更多的信息。
10. Job控制
假設(shè)你正在一個(gè)終端窗口上工作,并且正在運(yùn)行一個(gè)命令,該命令將花費(fèi)很長時(shí)間。在它完成之前,你不能與shell交互,但是我們希望繼續(xù)在我們的機(jī)器上工作,因此我們需要打開shell。我們可以控制我們的進(jìn)程如何運(yùn)行:
將工作發(fā)送到后臺(tái)
在命令后添加&號(hào)將在后臺(tái)運(yùn)行該命令:
?
sleep?1000?& sleep?1001?& sleep?1002?&
?
查看后臺(tái)進(jìn)程
將進(jìn)程從后臺(tái)移動(dòng)到前臺(tái)
要將進(jìn)程移出后臺(tái),只需指定所需的進(jìn)程ID。如果不帶任何選項(xiàng)地運(yùn)行fg,它將帶回最近的后臺(tái)進(jìn)程。
審核編輯:湯梓紅
評論
查看更多