在這篇指南中,我們會逐步對進程做基本的了解,然后簡要看看如何用特定命令管理 Linux 進程。
進程(process)是指正在執(zhí)行的程序;是程序正在運行的一個實例。它由程序指令,和從文件、其它程序中讀取的數據或系統(tǒng)用戶的輸入組成。
進程的類型
在 Linux 中主要有兩種類型的進程:
- 前臺進程(也稱為交互式進程) - 這些進程由終端會話初始化和控制。換句話說,需要有一個連接到系統(tǒng)中的用戶來啟動這樣的進程;它們不是作為系統(tǒng)功能/服務的一部分自動啟動。
- 后臺進程(也稱為非交互式/自動進程) - 這些進程沒有連接到終端;它們不需要任何用戶輸入。
什么是守護進程(daemon)
這是后臺進程的特殊類型,它們在系統(tǒng)啟動時啟動,并作為服務一直運行;它們不會死亡。它們自發(fā)地作為系統(tǒng)任務啟動(作為服務運行)。但是,它們能被用戶通過 init 進程控制。
Linux 進程狀態(tài)
在 Linux 中創(chuàng)建進程
(LCTT 譯注:此節(jié)原文不確,根據譯者理解重新提供)
在 Linux 中創(chuàng)建進程有三種方式:
fork() 方式
使用 fork() 函數以父進程為藍本復制一個進程,其 PID號與父進程 PID 號不同。在 Linux 環(huán)境下,fork() 是以寫復制實現的,新的子進程的環(huán)境和父進程一樣,只有內存與父進程不同,其他與父進程共享,只有在父進程或者子進程進行了修改后,才重新生成一份。
system() 方式
system() 函數會調用 /bin/sh –c command 來執(zhí)行特定的命令,并且阻塞當前進程的執(zhí)行,直到 command 命令執(zhí)行完畢。新的子進程會有新的 PID。
exec() 方式
exec() 方式有若干種不同的函數,與之前的 fork() 和 system() 函數不同,exec() 方式會用新進程代替原有的進程,系統(tǒng)會從新的進程運行,新的進程的 PID 值會與原來的進程的 PID 值相同。
Linux 如何識別進程?
由于 Linux 是一個多用戶系統(tǒng),意味著不同的用戶可以在系統(tǒng)上運行各種各樣的程序,內核必須唯一標識程序運行的每個實例。
程序由它的進程 ID(PID)和它父進程的進程 ID(PPID)識別,因此進程可以被分類為:
- 父進程 - 這些是在運行時創(chuàng)建其它進程的進程。
- 子進程 - 這些是在運行時由其它進程創(chuàng)建的進程。
init 進程
init 進程是系統(tǒng)中所有進程的父進程,它是啟動 Linux 系統(tǒng)后第一個運行的程序;它管理著系統(tǒng)上的所有其它進程。它由內核自身啟動,因此理論上說它沒有父進程。
init 進程的進程 ID 總是為 1。它是所有孤兒進程的收養(yǎng)父母。(它會收養(yǎng)所有孤兒進程)。
查找進程 ID
你可以用 pidof 命令查找某個進程的進程 ID:
? 查找 Linux 進程 ID
要查找當前 shell 的進程 ID 以及它父進程的進程 ID,可以運行:
? 查找 Linux 父進程 ID
在 Linux 中啟動進程
每次你運行一個命令或程序(例如 cloudcmd - CloudCommander),它就會在系統(tǒng)中啟動一個進程。你可以按照下面的方式啟動一個前臺(交互式)進程,它會被連接到終端,用戶可以發(fā)送輸入給它:
? 啟動 Linux 交互進程
Linux 后臺任務
要在后臺(非交互式)啟動一個進程,使用 & 符號,此時,該進程不會從用戶中讀取輸入,直到它被移到前臺。
? 在后臺啟動 Linux 進程
你也可以使用 Ctrl + Z 暫停執(zhí)行一個程序并把它發(fā)送到后臺,它會給進程發(fā)送 SIGSTOP 信號,從而暫停它的執(zhí)行;它就會變?yōu)榭臻e:
要在后臺繼續(xù)運行上面被暫停的命令,使用 bg 命令:
要把后臺進程發(fā)送到前臺,使用 fg 命令以及任務的 ID,類似:
? Linux 后臺進程任務
Linux 中進程的狀態(tài)
在執(zhí)行過程中,取決于它的環(huán)境一個進程會從一個狀態(tài)轉變到另一個狀態(tài)。在 Linux 中,一個進程有下面的可能狀態(tài):
- Running - 此時它正在運行(它是系統(tǒng)中的當前進程)或準備運行(它正在等待分配 CPU 單元)。
- Waiting - 在這個狀態(tài),進程正在等待某個事件的發(fā)生或者系統(tǒng)資源。另外,內核也會區(qū)分兩種不同類型的等待進程;可中斷等待進程(interruptible waiting processes) - 可以被信號中斷,以及不可中斷等待進程(uninterruptible waiting processes)- 正在等待硬件條件,不能被任何事件/信號中斷。
- Stopped - 在這個狀態(tài),進程已經被停止了,通常是由于收到了一個信號。例如,正在被調試的進程。
- Zombie - 該進程已經死亡,它已經停止了但是進程表(process table)中仍然有它的條目。
如何在 Linux 中查看活躍進程
有很多 Linux 工具可以用于查看/列出系統(tǒng)中正在運行的進程,兩個傳統(tǒng)眾所周知的是 ps 和 top 命令:
1. ps 命令
它顯示被選中的系統(tǒng)中活躍進程的信息,如下圖所示:
? 列出 Linux 活躍進程
2. top - 系統(tǒng)監(jiān)控工具
top 是一個強大的工具,它能給你提供 運行系統(tǒng)的動態(tài)實時視圖,如下面截圖所示:
? 列出 Linux 正在運行的程序
3. glances - 系統(tǒng)監(jiān)控工具
glances 是一個相對比較新的系統(tǒng)監(jiān)控工具,它有一些比較高級的功能:
? Glances – Linux 進程監(jiān)控
還有很多你可以用來列出活躍進程的其它有用的 Linux 系統(tǒng)監(jiān)視工具,打開下面的鏈接了解更多關于它們的信息:
如何在 Linux 中控制進程
Linux 也有一些命令用于控制進程,例如 kill、pkill、pgrep 和 killall,下面是一些如何使用它們的基本事例:
? 控制 Linux 進程
想要深入了解如何使用這些命令,在 Linux 中殺死/終止活躍進程,可以點擊下面的鏈接:
注意當你系統(tǒng)僵死(freeze)時你可以使用它們殺死 Linux 中的不響應程序。
給進程發(fā)送信號
Linux 中控制進程的基本方法是給它們發(fā)送信號。你可以發(fā)送很多信號給一個進程,運行下面的命令可以查看所有信號:
? 列出所有 Linux 信號
要給一個進程發(fā)送信號,可以使用我們之前提到的 kill、pkill 或 pgrep 命令。但只有被編程為能識別這些信號時程序才能響應這些信號。
大部分信號都是系統(tǒng)內部使用,或者給程序員編寫代碼時使用。下面是一些對系統(tǒng)用戶非常有用的信號:
- SIGHUP 1 - 當控制它的終端被被關閉時給進程發(fā)送該信號。
- SIGINT 2 - 當用戶使用 Ctrl+C 中斷進程時控制它的終端給進程發(fā)送這個信號。
- SIGQUIT 3 - 當用戶發(fā)送退出信號 Ctrl+D 時給進程發(fā)送該信號。
- SIGKILL 9 - 這個信號會馬上中斷(殺死)進程,進程不會進行清理操作。
- SIGTERM 15 - 這是一個程序終止信號(kill 默認發(fā)送這個信號)。
- SIGTSTP 20 - 它的控制終端發(fā)送這個信號給進程要求它停止(終端停止);通過用戶按 Ctrl+Z 觸發(fā)。
下面是當 Firefox 應用程序僵死時通過它的 PID 殺死它的 kill 命令事例:
使用它的名稱殺死應用,可以像下面這樣使用 pkill 或 killall:
更改 Linux 進程優(yōu)先級
在 Linux 系統(tǒng)中,所有活躍進程都有一個優(yōu)先級以及 nice 值。有比點優(yōu)先級進程有更高優(yōu)先級的進程一般會獲得更多的 CPU 時間。
但是,有 root 權限的系統(tǒng)用戶可以使用 nice 和 renice 命令影響(更改)優(yōu)先級。
在 top 命令的輸出中, NI 顯示了進程的 nice 值:
? 列出 Linux 正在運行的進程
使用 nice 命令為一個進程設置 nice 值。記住一個普通用戶可以給他擁有的進程設置 0 到 20 的 nice 值。
只有 root 用戶可以使用負的 nice 值。
要重新設置一個進程的優(yōu)先級,像下面這樣使用 renice 命令:
就是這些!如果你有任何問題或者想法,通過下面的反饋框和我們分享吧。
作者簡介:
Aaron Kili 是一個 Linux 和 F.O.S.S(Free and Open-Source Software) 愛好者,一個 Linux 系統(tǒng)管理員、web 開發(fā)員,現在也是 TecMint 的內容創(chuàng)建者,他喜歡和電腦一起工作,他相信知識共享。
評論
查看更多