1. 程式人生 > >程序建立和執行

程序建立和執行

簡單的說,每個應用在執行時就會產生一個程序,這個程序就對這個應用負責,掌握這個應用的執行狀態。

可是為什麼還要用一個程序來控制一個應用呢,下面將會簡單的解釋一下。

現在的應用對於資源的要求都是獅子大開口,開口就是幾個G,一臺電腦的記憶體一般也就幾個G,總不能一臺電腦就跑這一個應用吧。為了解決這個問題,作業系統就使用了虛擬記憶體,讓每個程序代表一個應用,給每個程序一種自己獨霸整臺電腦的假象,然後作業系統進行上下文切換,只把這個程序正好需要使用的資源放進記憶體;這樣每個程序都有自己獨有的資源。

建立程序

建立程序需要一個系統呼叫 fork(),fork可以建立一個和當前程序映像一樣的程序;成功時建立子程序並返回子程序的pid,失敗時不會建立子程序,返回-1並設定相應的errno。

順便介紹一下pid,pid是程序的ID,資料型別是pid_t,在Linux中被定義為int。可以呼叫 getpid()來獲得呼叫程序的pid,還可以通過呼叫 getppid() 來獲得呼叫程序的父程序的pid。

執行程序

執行程序需要呼叫 exec 系統呼叫,但是不存在單一的exec函式,他是由一系列的exec函式組成的。

以一個最簡單的呼叫 execl() 為例:

  • 成功的execl()呼叫改變 地址空間 和程序映像
  • 所有的掛起的訊號都會丟失
  • 捕捉到的所有訊號都會還原為預設處理方式
  • 丟棄所有的記憶體鎖
  • 大多數程序的屬性會還原成預設值(pid 父程序的pid 優先順序 所屬的使用者和組 不會變)
  • 清空和程序記憶體地址空間相關的所有資料,包括所有對映的檔案

終止程序

終止程序使用的是 exit() 系統呼叫,引數用於表示程序的推出狀態, EXIT_SUCCESSEXIT_FAILURE 這兩個可移植的巨集分別表示成功和失敗(也可以使用0和非0值來表示,不過可移植性就差了)。

簡單的表示成功退出就使用

exit(EXIT_SUCCESS);

這個系統呼叫會先完成在使用者空間需要做的事,再呼叫_exit()再處理核心中的事。

在使用者空間做的事

  • 呼叫任何由 atexit()on_exit() 註冊的函式,按在系統中註冊的相反順序。(假如在exit()前運行了atexit(a) atexit(b),那麼在呼叫exit()後就會先執行b再執行a )
  • 清空所有已開啟的標準I/O流
  • 刪除有tmpfile()函式建立的所有臨時檔案

核心會清理程序所建立的 不再使用的所有資源這包括但不侷限於:分配記憶體 開啟檔案和System Ⅴ的訊號量。清理完成後,核心會摧毀程序,並告知父程序其子程序已經終止。

參考源