目錄
一、什么是程序替換
1.1程序替換的原理
1.2更改為多進(jìn)程版本
二、各種exe接口
2.2execlp
??編輯
2.2execv
2.3execle、execve、execvpe
一、什么是程序替換
1.1程序替換的原理

就相當(dāng)于在執(zhí)行一個(gè)程序時(shí),要從磁盤中將新的數(shù)據(jù)和代碼加載到內(nèi)存中,將老程序的數(shù)據(jù)和代碼替換掉,這個(gè)現(xiàn)象就叫做程序替換。程序替換過程中并沒有創(chuàng)建新的進(jìn)程,而作為用戶我們沒有資格去直接進(jìn)行程序替換,所以如果想實(shí)現(xiàn)程序替換,就必須使用系統(tǒng)調(diào)用execl。
即pcb這個(gè)內(nèi)核數(shù)據(jù)結(jié)構(gòu)不換,代碼和數(shù)據(jù)換了。
第一個(gè)參數(shù)*Path是要尋找的程序,第二個(gè)參數(shù)*arg表示你想如何執(zhí)行,而最后的...是可變參數(shù)列表。
我們可以通過這個(gè)指令來對(duì)ls指令進(jìn)行模擬。
可以看到 ls命令很順利的執(zhí)行了,可pccontrol.c最后一個(gè)一個(gè)printf卻沒有執(zhí)行,這是為什么呢?
答案很簡(jiǎn)單,因?yàn)槌绦虮惶鎿Q了。
execl只有失敗返回沒有成功返回。 比如給定一個(gè)不存在的路徑。此時(shí)執(zhí)行完畢后如果去echo $?就可以看到錯(cuò)誤碼為1。如果成功替換完成,不創(chuàng)建新的進(jìn)程。
?而我們創(chuàng)建一個(gè)進(jìn)程,是先創(chuàng)建PCB、地址空間、頁表,然后再把程序加載到內(nèi)存,而程序替換所做的工作就是加載。
1.2更改為多進(jìn)程版本
?我們也可以創(chuàng)建一個(gè)子進(jìn)程,讓子進(jìn)程去進(jìn)行程序替換,這樣父進(jìn)程就可以得到運(yùn)行結(jié)果,因?yàn)檫M(jìn)程具有獨(dú)立性,創(chuàng)建子進(jìn)程后,當(dāng)要讓子進(jìn)程去進(jìn)行程序替換時(shí)就會(huì)發(fā)生寫實(shí)拷貝,開辟新的空間,這樣就不會(huì)影響父進(jìn)程。
所以我們的shell運(yùn)行原理我們也可以類推出來,當(dāng)我們?cè)趕hell中輸入指令時(shí),就會(huì)創(chuàng)建一個(gè)子進(jìn)程,然后shell去wait等待子進(jìn)程,子進(jìn)程進(jìn)行程序替換發(fā)生寫時(shí)拷貝開辟新的空間,然后去執(zhí)行。
二、各種exe接口
我們可以看到,一共有6個(gè)接口, 加上execv一共有7個(gè)接口。
文章來源:http://www.zghlxwxcb.cn/news/detail-847066.html
2.2execlp
?
execlp,最后為p(PATH)的不需要告訴操作系統(tǒng)絕對(duì)路徑,只需要告訴文件名。系統(tǒng)進(jìn)行替換時(shí)會(huì)自動(dòng)去PATH環(huán)境變量中查找。
?
最后的執(zhí)行結(jié)果和execl是一樣的?。
2.2execv
第一個(gè)參數(shù)是絕對(duì)或相對(duì)路徑,第二個(gè)參數(shù)是argv,即命令行參數(shù)表,類似于main函數(shù)的參數(shù)。
而exec結(jié)尾為l表示list,即將元素以鏈表的形式傳。
而v結(jié)尾表示vector,即以數(shù)組形式傳。
execvp類比于上面的execlp
exec*可以執(zhí)行系統(tǒng)的指令,也可以執(zhí)行自己的程序,無論是什么語言,都可以在linux下跑。因?yàn)樗械恼Z言運(yùn)行之后都是進(jìn)程。
2.3execle、execve、execvpe
區(qū)別就是最后帶上了環(huán)境變量的一個(gè)參數(shù)。
首先如果不使用帶環(huán)境變量的調(diào)用,可以通過顯示傳的方式傳給操作系統(tǒng)。我們也可以在C語言寫的程序中去通過傳參給一段C++ 代碼編譯成的可執(zhí)行程序。
通過以上我們可以看到,通過子進(jìn)程完成了進(jìn)程切換成功運(yùn)行了mytest文件并且將命令行參數(shù)傳給了mytest的argv,父進(jìn)程也成功回收了子進(jìn)程。
以上傳了命令行參數(shù),那環(huán)境變量該如何傳給要替換的程序呢?
當(dāng)我們不顯示去傳環(huán)境變量表時(shí)會(huì)發(fā)生什么呢??
子進(jìn)程默認(rèn)可以通過地址空間繼承的方式,讓所有子進(jìn)程拿到環(huán)境變量。
進(jìn)程程序替換,不會(huì)替換環(huán)境變量數(shù)據(jù)。
1.如果我們想讓子進(jìn)程繼承全部的環(huán)境變量,直接就能拿到
2.如果單純新增的話使用putenv("GA=AAAAAA");
3.如果想設(shè)置全新的環(huán)境變量,就可以用到execle
再次運(yùn)行,環(huán)境變量就變成我們?cè)O(shè)置的全新的環(huán)境變量了,也叫覆蓋方式。
?而這么多的接口功能上基本上不存在太大的差異,只是傳參的區(qū)別以及使用方式不同,而程序替換真正的系統(tǒng)調(diào)用只有一個(gè),就是上圖所示的execve,其余所有的調(diào)用都是封裝了execve。文章來源地址http://www.zghlxwxcb.cn/news/detail-847066.html
到了這里,關(guān)于Linux :進(jìn)程的程序替換的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!