進程空間布局:
text segment(文本段):包含進程啟動並執行機器指令
initiallized data segment(初始化資料區段):包含顯式初始化的全域變數和靜態變數
uninitiallized data segment(未初始化資料區段):包含未顯式初始化的全域變數和靜態變數
stack(棧):動態增長和收縮,由stack frames(棧幀)組成
heap(堆):運行時動態分配,堆頂為program break
虛擬記憶體管理(空間局部性,時間局部性):
將記憶體劃分為page(頁)。
每個程式僅有部分分頁駐留在實體記憶體,構成了resident set(駐留集)。未使用的頁儲存在swap area(交換區)。
交換區是磁碟保留地區,需要時載入實體記憶體。進程訪問的頁不再實體記憶體,發送page fault,核心掛起進程執行,並從磁碟將頁面載入。
核心為每個進程維護一張page table(頁表)
command-line arguments(argc,argv)命令列參數
environment list環境列表,程式執行時載入使用者或系統設定的變數
setjmp,longjmp:跳轉將此時的環境(此時棧的位置,pc,寄存器等資料儲存)儲存(動作類似於函數壓棧,不過是壓入特殊位置,跳到特殊位置),跳轉到其他位置,並在跳回來恢複。
記憶體配置:
調整program break:
int brk(void *end_data_segment);//program break設定為end_data_segment處
void* sbrk(intptr_t increment);program break增加increment
malloc(),free(),calloc(),realloc(),
memalign(),posix_memalign();//分配對齊的記憶體
alloca()在堆棧上分配
記憶體配置上也可能出現記憶體流失,因此可以使用glibc的malloc調試工具和調試庫valgrind等等
記憶體配置上也可能出現記憶體片段,可以針對程式使用不同的分配策略(如C++ new的多層分配策略)
進程式控制制:
fork();//返回兩次,一次在子進程內返回0,一次在父進程內返回子進程pid;
進程fork,子進程和其共用頁,其中程式碼片段可讀無法修改,其餘部分COW(寫時複製)
vfork();//補位子進程複製頁表,虛擬記憶體頁,共用父進程,直到成功exec(),_exit()退出;在子進程exec()或_exit()之前暫停執行父進程
_exit(status);//定義終止狀態後終止
exit(status),//先後調用退出處理常式,重新整理stdio流緩衝,調用_exit()
退出處理常式:atexit();註冊,glibc提供了帶參數的退出處理on_exit();
其中退出處理常式的執行順序與調用順序相反
wait(int * status);//阻塞到子進程終止,將終止資訊通過status指向的整形變數返回
waitpid(pid, int* status, int option);//根據pid值得不同,標識等待不同的子進程。
同時,還有使用一組宏判斷status。詳見wait
waitid();//linux2.6.9加入
wait3();wait4();//
孤兒進程:當父進程終止後,子進程的父進程變為ID為1的init進程;
殭屍進程:當父進程尚未調用wait()之前子進程終止,該子進程尚未被清理被稱為殭屍進程(釋放大部分資源);
SIGCHLD為子進程終止時限父進程發送的訊號
execve():詳見man
exec()之後,檔案描述符會保留
system()函數執行shell命令