深入理解程序(七) 程式替換

2021-10-19 05:17:24 字數 2858 閱讀 2393

用乙個新的程式去替換乙個程序正在排程的程式的資訊。

程序執行乙個程式時,我們需要將該程式載入到記憶體中,然後再通過該程序的虛擬位址空間利用頁表對映到資料實際上存放的物理記憶體中,通過這樣的方式,就實現了程序與程式之間的關聯。如果我們此時將另乙個程式載入到記憶體中,然後修改這種對映關係(也就是修改頁表),那麼程序就與這個新程式關聯起來,那麼該程序就不再執行原來的程式,而是會去執行這個新的程式。

本質上就是去替換乙個程序pcb在記憶體中的對應的**和資料(載入新程式到記憶體——>更新頁表資訊——>初始化虛擬位址空間),然後這個程序pcb重新開始執行這個新的程式

我們進行程式替換的方式是使用exec函式簇。該函式簇中包含了六個函式。分別是下面六個:

int execl(const char *path, const char *arg, ...);

int execlp(const char *file, const char *arg, ...);

int execle(const char *path, const char *arg, ..., char *const envp);

int execv(const char *path, char *const ar**);

int execvp(const char *file, char *const ar**);

int execve(const char *path, char *const ar**, char *const envp);

execl函式

(1)函式原型

int execl(const char *path, const char *arg, ...)
(2)函式引數

該函式的引數的引數個數是不定的。

第乙個引數:想要替換的程式的路徑(就是使用這個程式去替換正在執行的程式)

最後乙個引數:null,作為執行引數結束的標誌

其餘引數:數量不定,都是作為新程式的執行引數而傳入的

(3)舉個栗子

第乙個cpp程式:test.cpp

#include #include using namespace std;

int main()

{ cout<

int main(int argc,char* ar**)

{ for(int i=0;i執行結果:

程式解析:

test.cpp

中輸出hello後,進行程式替換,於是執行execl這個程式,而execl程式的功能就是列印出自己的執行引數,所以它就根據execl函式知道傳入的執行引數有兩個。

execv函式

(1)函式原型

int execv(const char *path, char *const ar**);

(2)函式引數第乙個引數:同execl第乙個引數

第二個引數:乙個字串陣列。這個字串陣列中存放的字串就是作為新程式的執行引數而傳入的,以null結尾。同execl相比,該函式是先將執行引數全部寫在乙個字串陣列中,然後再將該字串陣列傳入函式中。

大家肯定很奇怪,明明有六個函式,但是為什麼在上面我只講了兩個,因為這六個函式如果仔細觀察的話就會發現

它們之間是有規律的,而這種規律就能幫助我們掌握其餘的四個函式。

(1)函式名中有l和有v的區別

l是通過不定參來賦予新程式的執行引數

v是通過字串指標陣列來進行賦值的

(2)函式名中是否有p的區別

在於第乙個引數的不同,如果沒p,那麼需要提供乙個帶路徑的檔名;如果有p那麼只需要提供檔名稱即可,因為它缺省會去path環境變數的路徑中去尋找

(3)函式名中有沒有e的區別

表示這個程序的環境變數需不需進行初始化,如果有e則表示需要初始化;沒有e則表示使用預設的環境變數

比如,你在命令列中輸入語句ls -l,然後顯示出了一大堆的檔案資訊,那麼linux是如何執行它的呢?

首先你要知道一點,實際上ls也是乙個程式,和你自己寫的程式沒區別。當我們輸入ls時其實就相當於執行自己的程式一樣,而這個程式的父程序就是shell程式。

當我們輸入乙個命令ls時,shell程式會對你的輸入進行解析,然後建立乙個子程序,而這個子程序就是通過程式替換來執行這個新程式ls的,而程式的替換的方式就是通過上面的exec函式簇,而-l也會被作為執行引數傳入

七、注意

原先的**和資料是否還存在?

一般來說,我們是呼叫fork函式之後,在子程序中使用程式替換。所以原先的**和資料實際上是屬於父程序的,因此它們是否存在也取決於父程序。如果父程序還在使用它們,那麼就還存在;如果父程序不再使用它們,那麼作業系統就會將其釋放掉。

程式替換之後,執行完新程式之後,也是不會去執行原程式的。換句話說,在原程式呼叫exec函式的地方之後的語句是不會執行的。

上面的六個函式執行成功的時候是沒有返回值的,只有當執行失敗的時候,返回-1

深入理解 linux swapper 程序

對於父程序已經終止的所有程序,他們的父程序都改變為init。在乙個程序終止時,核心逐個檢查所有活動的程序,以判斷他是否是正要終止程序的子程序,如果是,則將該程序id更改為1,這種方法保證了每個程序都有乙個父程序。如果子程序在父程序終止之前終止,父程序如何能做相應檢驗得到子程序的終止狀態呢?對此的回答...

深入理解Linux核心 程序

1 程序的靜態特性 程序 程式執行時的乙個例項 程序描述符 task struct 程序的基本資訊 thread info 指向記憶體區描述符的指標 mm struct 程序相關的tty tty struct 當前目錄 fs struct 指向 檔案描述符的指標 files struct 所接收的訊...

深入理解緩衝區(七)

資料緩衝區塊 位址連續的 多個快取塊的組合。記憶體中真正的資料存放區。緩衝區的組成之一。快取塊 最小的快取資料塊的快取單位。被資料快取塊包含。4.1.4.1 buf的整體結構 在src backend storage buffer buf init.c中有initbufferpool函式,描述了基本...