標籤:而在 虛擬記憶體 buffer 工作資料夾 而且 初始化 項目 線性 路徑
? 進程
是指一個具有獨立功能的程式在某個資料集上的一次動態運行過程,它是系統進行資源分派和調度的最小單元。
? 一個進程能夠擁有多個線程。每一個線程必須有一個父進程。
? 進程特性:並發、動態、互動、獨立和非同步。
進程的生命週期
進程的五種狀態
? 執行(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。
Android進程命令查看