1.進程創建
1.1fork函數初識
在linux中fork函數是?常重要的函數,它從已存在進程中創建?個新進程。新進程為?進程,?原進 程為?進程。
#include <unistd.h>
pid_t fork(void);
返回值:?進程中返回0,?進程返回?進程id,出錯返回-1
進程調?fork,當控制轉移到內核中的fork代碼后,內核做:
? 分配新的內存塊和內核數據結構給?進程
? 將?進程部分數據結構內容拷???進程
? 添加?進程到系統進程列表當中
? fork返回,開始調度器調度

當?個進程調?fork之后,就有兩個?進制代碼相同的進程。?且它們都運?到相同的地?。但每個進 程都將可以開始它們??的旅程,看如下程序
int main( void )
{
pid_t pid;
printf("Before: pid is %d\n", getpid());
if ( (pid=fork()) == -1 )perror("fork()"),exit(1);
printf("After:pid is %d, fork return %d\n", getpid(), pid);
sleep(1);
return 0;
}
運?結果:
[root@localhost linux]# ./a.out
Before: pid is 43676
After:pid is 43676, fork return 43677
After:pid is 43677, fork return 0
這?看到了三?輸出,??before,兩?after。進程43676先打印before消息,然后它有打印after。 另?個after消息有43677打印的。注意到進程43677沒有打印before,為什么呢?如下圖所?

所以,fork之前?進程獨?執?,fork之后,??兩個執?流分別執?。注意,fork之后,誰先執?完 全由調度器決定。
1.2 fork的返回值
fork()
?是 Unix/Linux 系統創建新進程的系統調用,其特殊之處在于?"一次調用,兩次返回":
-
在父進程中返回?子進程的 PID(>0)
-
在子進程中返回?0
-
出錯時返回?-1
1.3寫時拷貝
通常,??代碼共享,??再不寫?時,數據也是共享的,當任意??試圖寫?,便以寫時拷?的? 式各??份副本。具體?下圖

核心概念:
寫時拷貝是一種? 延遲內存復制?的優化策略,父子進程? 共享同一份物理內存,直到某個進程嘗試? 修改內存頁?時,操作系統才會進行實際復制
關于觸發寫實拷貝的條件是:
-
CPU 觸發?頁錯誤(Page Fault)
-
內核檢查錯誤原因是否為 COW
-
分配新的物理頁,復制原頁內容
-
修改故障進程的頁表,指向新物理頁
-
恢復進程執行
1。4?fork調?失敗的原因
系統中有太多的進程
實際??的進程數超過了限制
2.終止進程
進程終?的本質是釋放系統資源,就是釋放進程申請的相關內核數據結構和對應的數據和代碼
2-1 進程退出場景
? 代碼運?完畢,結果正確
? 代碼運?完畢,結果不正確
? 代碼異常終?
2-2 進程常?退出?法
正常終?(可以通過 echo $? 查看進程退出碼):
1. 從main返回
2. 調?exit
3. _exit
2-2-1 退出碼
退出碼(退出狀態)可以告訴我們最后?次執?的命令的狀態。在命令結束以后,我們可以知道命令
是成功完成的還是以錯誤結束的。其基本思想是,程序返回退出代碼 0 時表?執?成功,沒有問題。
代碼 1 或 0 以外的任何代碼都被視為不成功。
Linux Shell 中的主要退出碼

2.3 exit函數
1. 標準庫函數 vs 系統調用
函數原型 | 所屬標準 | 關鍵差異 |
---|---|---|
void exit(int status) | C標準庫 | 執行完整清理:刷新緩沖區、調用atexit注冊函數 |
void _exit(int status) | POSIX系統調用 | 直接終止進程,不執行I/O緩沖清理 |
資源回收關鍵機制
資源類型 | 處理方式 | 例外情況 |
---|---|---|
文件描述符 | 全部關閉 | 無 |
內存泄漏 | 用戶態內存不會自動釋放 | 需依賴OS內核回收 |
臨時文件 | 未刪除的臨時文件保留 | 需手動unlink |
共享內存 | 引用計數減1 | 計數為0時才釋放 |
注意事項:
1. 多線程環境
-
調用
exit()
會終止?整個進程(所有線程) -
替代方案:
-
pthread_exit()
?終止當前線程 -
主線程使用
return
退出
-
2. 信號處理沖突
-
在信號處理函數中調用
exit()
是安全的 -
避免在
SIGKILL
/SIGSTOP
處理中操作(信號不可捕獲)
2-3-1?return退出
return是?種更常?的退出進程?法。執?return n等同于執?exit(n),因為調?main的運?時函數會 將main的返回值當做 exit的參數。