24.Linux/Unix 系統程式設計手冊(上) -- 程序的建立
阿新 • • 發佈:2018-12-13
1.fork, exit, wait, execve 簡介 1.fork() 允許一進城建立一個子程序。子程序獲取父程序的棧,資料段,堆和執行文字段。 2.exit() 終止一程序,將程序佔用的所有資源歸還核心。 庫函式 exit() 位於系統呼叫 _exit() 之上。父子程序一般只有一個會通過呼叫 exit() 退出, 而另外一個程序則應該使用 _exit() 終止。 3.系統呼叫 wait(&status)的目的有二:其一,如果子程序尚未呼叫 exit 終止,那麼 wait() 會掛起父程序, 直到子程序終止。其二,子程序的終止狀態通過 wait 的 status 引數返回。 4.系統呼叫 execve(pathname, argv, envp) 載入一個新的程式(路徑名為 pathname, 引數列表為 argv, 環境變數為 envp) 到當前程序的記憶體。這將丟棄現存的程式文字段,併為新程式重新建立棧,資料段以及堆。 5.vfork() 將保證子程序優先於父程序獲得排程使用 cpu. 現在不建議使用。 2.fork 的記憶體語義 fork 之後常常伴隨著 exec, 這會用新程式替換程序的程式碼段,並重新初始化其資料段,堆段和棧段。大多數現代 Unix 系統使用 2種技術避免這種浪費: 1.核心將每個程序的程式碼段標記為只讀,從而使得程序無法修改自身的程式碼。 2.對於父程序資料段,堆段和棧段中的個頁,核心採用寫時複製(copy-on-write)技術來處理。最初核心做了一些設定,令這些段的頁表項 指向與父程序相同的實體記憶體頁,並將這些頁面自身標記為只讀。呼叫 fork 後,核心會捕獲所有父程序或者子程序對這些頁面的修改企圖, 並將要修改的頁面建立拷貝頁。系統將新的拷貝頁分配給遭記憶體捕獲的程序,還會對子程序的相關頁表進行適當的調整。