Linux 應用開發之進程和程序

1. 進程和程序

進程是一個可執行程序的實例,程序包含了一系列信息文件,這些信息描述瞭如何在運行期間創建一個進程:

可以用一個程序來創建很多進程。

從內核角度來看:

2. 進程號和父進程號

每個進程都有一個進程號 PID,是一個正數,唯一標識系統中的某個進程。

#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);
#include <sys/types.h>
#include <unistd.h>

pid_t getppid(void);

3. 進程內存佈局

每個進程所分配的內存都由很多虛擬內存邏輯劃分的部分,稱之爲 "段":

初始化數據段和未初始化數據段又常被稱爲用戶初始化數據段和零初始化數據段。

size 命令可以顯示二進制文件的文本段,初始化數據段,未初始化數據段的大小。

4. 虛擬內存管理

linux 內核採用虛擬內存管理技術,該技術利用了大多數程序的一個典型特徵,即訪問局部性:要求高效使用 CPU 和 RAM(物理內存) 資源:

正是因爲局部性特徵,使得程序即便在僅有部分地址空間存在於  RAM 中,依然可以獲得執行。

虛擬內存的規劃之一就是將每個程序使用的內存切割成小型的,固定大小的 "頁"  單元。相應的,將 RAM 劃分成一系列與虛擬頁尺寸相同的頁幀:

頁面的大小通常爲 4096 個字節,但也有的實現使用更大的頁面。

內核中維護了一張頁表,該頁表描述了每頁在進程虛擬地址空間中的位置:頁表中的每個條目要麼指出這個虛擬頁面在 RAM 中的具體位置,要麼表明其駐留在磁盤上。

進程虛擬地址空間中,並非所有的地址範圍都需要頁表條目:

由於內核能夠爲進程分配和釋放頁和頁表條目,所以進程的有效地址範圍在其聲明週期內可以發生變化:

虛擬內存的實現需要硬件中分頁內存管理單元 (PMMU) 的支持,PMMU 把要訪問的每個虛擬地址轉換成相應的物理內存地址,當特定虛擬內存地址所對應的頁沒有駐留在 RAM 中時,將以頁面錯誤通知內核。

虛擬內存管理使虛擬地址空間與 RAM 物理地址隔離,帶來的優點:

5. 棧和棧幀

棧駐留在內存的高端,並向下增長,專用寄存器——棧指針 (stack pointer),用於跟蹤當前棧頂。

每次函數調用時,會在棧上新分配一幀,每當函數返回,再從棧上將此幀移去。

通常將這裏的棧稱爲用戶棧,以便與內核棧加以區分,內核棧是每個進程駐留在內核內存中的內存區域,在執行系統調用的過程中供內核內部函數調用使用。

每個用戶棧包括的信息:

6. 命令行參數

要想從程序內的任一位置訪問部分或者全部內容,還有兩種方法:

argv 駐留於進程棧之上的一個內存區域,此區域可存儲的字節數有上限要求, <limits.h> 中的  ARG_MAX 常量規定了其大小,一般要求下限是 4096 個字節,調用 sysconf(_SC_ARB_MAX) 確定此值。

7. 環境列表

每個進程都有一個與其相關的稱之爲環境列表的字符串數組,或者簡稱爲環境:

大多數 shell 使用 export 添加環境變量:

export SHELL=/bin/bash

printenv 命令可以顯示當前的環境列表,export  命令不加任何參數時也可以達到此目的。

通過 /proc/PID/environ  文件可以檢查任一進程的環境列表。

8. 從程序中訪問環境

C 語言使用全局變量 char** environ 訪問列表。

#include <stdlib.h>

char *getenv(const char *name);

9. 修改環境

#include <stdlib.h>

int putenv(char *string);
#include <stdlib.h>

int setenv(const char *name, const char *value, int overwrite);
#include <stdlib.h>

int unsetenv(const char *name);
#include <stdlib.h>

int clearenv(void);

使用 setenv  和  clearenv()  可能導致內存泄漏:

10. 執行非局部跳轉

#include <setjmp.h>

int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);

編譯器優化會重組程序的指令執行順序,並在 CPU 寄存器中而非 RAM 中存儲某些變量,這些優化不會將 setjmp()  和 longjmp()  考慮在內,因而當有優化時,可能出錯。

程序中應該儘可能避免使用非局部跳轉。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/cnvcMBY8Ypv4SAMnuzSAUQ