• 進程
是指一個具有獨立功能的程序在某個數據集上的一次動態運行過程,它是系統進行資源分配和調度的最小單元。
• 一個進程能夠擁有多個線程。每一個線程必須有一個父進程。
• 進程特性:並發、動態、交互、獨立和異步。
進程的生命周期
進程的五種狀態
• 執行(TASK_RUNNING)
進程正在被CPU運行,或已經准備就緒隨時可由調度程序運行
• 僵屍(TASK_ZOMBIE)
當進程已停止執行,但其父進程還沒有調用wait()詢問其狀態時,則稱該進程處於僵死狀態。
• 停止(TASK_STOPPED)
當進程收到信號SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU時就會進入暫停狀態。可向其發送SIGCONT信號讓進程轉換到可執行狀態。
• 睡眠狀態
假設進程在內核態運行時須要等待系統的某個資源,此時該進程就會調用sleep_on()或interruptible_sleep_on()自願地放棄CPU的使用權。而讓調度程序去運行其它進程。這時稱其處於睡眠等待狀態。
– 可中斷(TASK_INTERRUPTIBLE)
進程在該狀態下。系統不會調度該進程運行。
當系統產生一個中斷。
或者釋放了進程正在等待的資源,
或者進程收到一個信號。
都能夠喚醒進程轉換到就緒狀態(就可以執行狀態)。
– 不可中斷(TASK_UNINTERRUPTIBLE)
除了不會由於收到信號而被喚醒。該狀態與可中斷睡眠狀態類似。但處於該狀態的進程僅僅有被使用wake_up()函數明白喚醒時才干轉換到可執行的就緒狀態。該狀態通常在進程須要不受干擾地等待或者所等待事件會非常快發生時使用。
進程上下文
• 每一個進程都有各自互不干涉的進程地址空間。該地址空間是大小為 4GB的線性虛擬空間,用戶所看到和接觸到的都是該虛擬地址,無法看到實際的物理內存地址。利用這樣的虛擬地址不但能起到保護操作系統的效果(用戶不能直接訪問物理地址),並且,更重要的是。用戶程序能夠使用比實際物理內存更大的地址空間。
• 4GB的進程地址空間會被分成兩個部分:用戶空間與內核空間。
• 用戶地址空間是從0到3GB(0xC0000000),
• 內核地址空間占領3GB到4GB。
• 用戶進程通常情況下僅僅能訪問用戶空間的虛擬地址,不能訪問內核空間的虛擬地址。
• 僅僅實用戶進程使用系統調用(代表用戶進程在內核態運行)時能夠訪問到內核空間。
• 每當進程切換時,用戶空間就跟着變化;
• 而內核空間由內核負責映射,它不會跟着進程改變。是固定的。
• 內核空間地址有自己相應的頁表,用戶進程各自有不同的頁表。
• 每一個進程的用戶空間都是全然獨立、互不相干的。
• BSS段:在採用段式內存管理的架構中。BSS段(bss segment)一般是指用來存放程序中未初始化的全局變量的一塊內存區域。
BSS是英文Block Started by Symbol的簡稱。BSS段屬於靜態內存分配。
• 數據段:在採用段式內存管理的架構中,數據段(data segment)一般是指用來存放程序中已初始化的全局變量的一塊內存區域。
數據段屬於靜態內存分配。
• BSS段:在採用段式內存管理的架構中,BSS段(bss segment)一般是指用來存放程序中未初始化的全局變量的一塊內存區域。BSS是英文Block Started by Symbol的簡稱。
BSS段屬於靜態內存分配。
• 數據段:在採用段式內存管理的架構中。數據段(data segment)一般是指用來存放程序中已初始化的全局變量的一塊內存區域。數據段屬於靜態內存分配。
• 代碼段:在採用段式內存管理的架構中,代碼段(code segment / text segment)一般是指用來存放程序執行代碼的一塊內存區域。這部分區域的大小在程序執行前就已經確定,而且內存區域通常屬於僅僅讀, 某些架構也同意代碼段為可寫。即同意自改動程序。
在代碼段中,也有可能包括一些僅僅讀的常數變量,比如字符串常量等。
• 棧(stack)在計算機科學中,是一種特殊的鏈表形式的數據結構,它的特殊之處在於僅僅能同意在鏈表的一端(稱為棧頂。英文為top)進行加入和刪除操作。另外堆棧數據結構的實現也能夠通過數組來完畢。棧Stack是存放程序中局部變量的內存區。另外棧stack用來保存函數調用的現場。棧stack由系統自己主動分配。用戶不須要關心其分配和釋放。
• 堆是指Heap,程序執行時供程序猿來支配的一段內存。 用於進程執行時動態分配內存。堆的大小不固定。可依據程序執行動態變化。
由程序中的new/delete等控制。
fork方法
• fork()函數用於從已存在的一個進程中創建一個新的進程,新進程稱為子進程,而原進程稱為父進程。
• 使用fork()函數得到的子進程是父進程的一個復制品,它從父進程處繼承了整個進程的地址空間,包含進程上下文、代碼段、進程堆棧、內存信息、打開的文件描寫敘述符、信號控制設定、進程優先級、進程組號、當前工作文件夾、根文件夾、資源限制和控制終端等,而子進程所獨有的僅僅有它的進程號、資源使用和計時器等。
• 區分父子進程:由於子進程差點兒是父進程的全然復制,所以父子進程會執行同一個程序。這就須要用一種方式來區分它們,並使它們照此執行。在父進程中的返回值是子進程的進程號,而在子進程中返回0。
因此,能夠通過返回值來判定該進程是父進程還是子進程。
• 開銷:使用fork()函數的代價是非常大的,它復制了父進程中的代碼段、數據段和堆棧段里的大部分內容,使得fork()函數的系統開銷比較大,並且運行速度頁不是非常快。
exec方法
• exec 函數族提供了在一個進程中啟動還有一個程序運行的方法。
• 它能夠依據指定的文件名稱或文件夾名找到可運行文件,並用它來代替原調用進程的數據段、代碼段和堆棧段,在運行完之后,原調用進程的內容除了進程號外,其它所有被新的進程替換了。
• 可運行文件既能夠是二進制文件。也能夠是Linux下不論什么可運行的腳本文件。
• 什么時候使用exec
• 當進程覺得自己不能再為系統和用戶做出不論什么貢獻時,就能夠調用 exec 函數族中的隨意一個函數讓自己重生
• 假設一個進程想運行還有一個程序。那么它就能夠調用 fork() 函數新建一個進程。然后調用exec 函數族中的隨意一個函數。這樣看起來就像通過運行應用程序而產生了一個新進程
• 查找方式:表1中的前4個函數的查找方式都是完整的文件文件夾路徑,而最后兩個函數(也就是以p 結尾的兩個函數)能夠僅僅給出文件名稱,系統就會自己主動依照環境變量“$PATH” 所指定的路徑進行查找。
• 參數傳遞方式:exec函數族的參數傳遞有兩種:一種是逐個列舉的方式。而還有一種則是將全部參數總體構造指針數組傳遞。
在這里是以函數名的第5位字母來區分的,字母為"l"(list)的表示逐個列舉參數的方式。其語法為constchar *arg;字母為“v”(vector)的表示將全部參數總體構造指針數組傳遞,其語法為char *const argv[]。這里的參數實際上就是用戶在使用這個可運行文件時所需的全部命令選項字符串(包含該可運行程序命令本身)。
要注意的是,這些參數必須以NULL結束。
• 環境變量: exec函數族能夠默認系統的環境變量,也能夠傳入指定的環境變量。這里以“e”(environment)結尾的兩個函數execle()和execve()就能夠在envp[]中指定當前進程所使用的環境變量。
exit方法
• 終止進程使用exit()和_exit()函數。當進程執行到exit()或_exit()函數時。進程會無條件的停止剩下的全部操作,清除各種數據結構。並終止本進程的執行。
• _exit()函數的作用是:直接使進程停止執行,清除其使用的內存空間,並清除其在內核中的各種數據結構;而exit()函數則在這些基礎上做了一些包裝,在執行退出之前加了若干道工序。
• exit()函數和_exit()函數的最大差別就在於exit()函數在終止當前進程之前要檢查該進程打開過哪些文件,把文件緩沖區中的內容寫回文件,也就是圖1中的“清理I/O緩沖”一項。
• 在Linux的標准函數庫中,有一種被稱作“緩沖I/O(buffered I/O)”的操作,其特征就是相應每個打開的文件。在內存中都有一片緩沖區。
• 每次讀文件時,會連續讀出若干條記錄,這樣在下次讀文件時就能夠直接從內存的緩沖區中讀取;相同,每次寫文件時,也不過寫入內存中的緩沖區,等滿足了一定的條件(如達到一定數量或遇到特定字符等。最典型的就是咱們的vim中使用的:w命令),再將緩沖區中的內容一次性寫入文件。
• 這樣的技術大大添加了文件讀寫的速度,但也給咱們的編程帶來了一些麻煩。比方有些數據你覺得已經被寫入到文件里,實際上由於沒有滿足特定的條件,它們還僅僅是被保存在緩沖區內,這時用_exit()函數直接將進程關閉掉,緩沖區中的數據就會丟失。
因此,若想保證數據的完整性,最好使用exit()函數。
•
cmd命令行相關進程命令
• ps -查看系統中進程的狀態
• USER表示啟動進程用戶
• PID表示進程標志號
• %CPU表示執行該進程占用CPU的時間與該進程總的執行時間的比例
• %MEM表示該進程占用內存和總內存的比例
• VSZ表示占用的虛擬內存大小,單位KB
• RSS為進程占用的物理內存值,單位KB
• TTY表示該進程建立時所相應的終端,假設顯示“?”表示不占用終端
• START為進程開始時間
• TIME為運行的時間
• COMMAND是相應的命令名
• STAT是進程的執行狀態
• D。 不可中斷的睡眠
• R。 就緒(在可執行隊列中)
• S, 睡眠
• T, 被跟蹤或停止
• Z。 終止(僵死)的進程
• W,沒有足夠的內存分頁可分配
• < ,高優先級的進程
• N,低優先級的進程
• L,有內存分頁分配並鎖在內存體內(實時系統或I/O)
• + ,前台進程
• s 。一個信息頭
• l ,多線程
• 參數介紹:
-A:顯示系統中全部進程的信息。
-e:顯示全部進程的信息。
-f:用ASCII字符顯示樹狀結構,表達程序間的相互關系
-l:以長格式顯示進程信息。
-r:僅僅顯示正在執行的進程。
-u:顯示面向用戶的格式(包含username、CPU及內存使用情況等信息)。
-x:顯示全部非控制終端上的進程信息。
-p:顯示由進程ID指定的進程的信息。
-t:顯示指定終端上的進程的信息。
-H: 顯示樹狀結構。表示程序間的相互關系
• top -顯示系統當前的進程狀況
• 第一行表示的項目依次為當前時間、系統啟動時間、當前系統登錄用戶數目、平均負載。
• 第二行顯示的是全部啟動的、眼下執行的、掛起(Sleeping)的和僵屍(Zombie)進程。
• 第三行顯示的是眼下CPU的使用情況,包含系統占用的比例、用戶使用比例、閑置(Idle)比例。
• 第四行顯示物理內存的使用情況,包含總的能夠使用的內存、已用內存、空暇內存、緩沖區占用的內存。
• 第五行顯示交換分區的使用情況,包含總的交換分區、使用的、空暇的和用於快速緩存的交換分區。
• PID(Process ID):進程標志號。是非零正整數
• USER:進程全部者的username
• PR:進程的優先級別
• NI:進程的優先級別數值
• VIRT:進程占用的虛擬內存值
• RES:進程占用的物理內存值
• SHR:進程使用的共享內存值
• STAT:進程的狀態。當中S表示休眠,R表示正在執行,Z表示僵死狀態,N表示該進程優先值是負數
• %CPU:該進程占用的CPU使用率
• %MEM:該進程占用的物理內存和總內存的百分比
• TIME:該進程啟動后占用的總的CPU時間
• COMMAND:進程啟動的啟動命令名稱
• 參數介紹
• d:指定更新的間隔,以秒計算。
• q:沒有不論什么延遲的更新。
假設使用者有超級用戶,則top命令將會以最高的優先序運行。
• c:顯示進程完整的路徑與名稱。
• S:累積模式,會將已完畢或消失的子進程的CPU時間累積起來。
• s:安全模式。
• i:不顯示不論什么閑置(Idle)或僵屍(Zombie)進程。
• n:顯示更新的次數,完畢后將會退出top。