天天看點

系統程式設計-程序-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程序-close-on-exec機制

我的相關博文:

PART1 

exec系列函數功能簡介

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

exec系列函數登場

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

正常操作是先fork一個子程序,然後在子程序中調用exec系列函數執行新的目标程式,

雖然exec系列函數執行成功不傳回,但是我們仍然i要使用wait或waitpid讓父程序給該子程序收屍,否則将會産生一個僵屍程序(子程序死了,老爸沒給收屍,子成為僵屍)!

并且,不論子程序内的exec系列函數執行成功或是失敗,我們都要在父程序給對其收屍!

待實驗,見實驗1(實驗1,使用execl),  思路:

讓子程序内調用exec系列函數執行的新程式的生命周期大概是5秒,觀察父程序wait成功且執行到wait後面的列印語句的時間,判斷是否也為5秒。

該系列函數辨識方法

該系列函數都以“exec”為字首,後面的字母有各自固定的含義,可以根據這點來進行區分,而無需強行記憶。看下圖詳解:

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

補充知識點:

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

讀完上面的小結,我們可以分析出,例如execl,其第一個參數pathname,必須要求是絕對路徑。

exec系列函數關系剖析

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

注意事項:

如果代碼想下圖這樣寫,因為exec函數執行出錯,但是後續代碼仍然會被執行,可是:目前程序的記憶體空間(堆、棧、資料區)可能已經被破壞,是以這種寫法是不妥的!

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

上圖代碼不妥,應該修改為下圖方式,即設定程序退出:

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

同時,若exec執行成功,則後續代碼不會被執行。

PART2

實驗部分 

實驗0

實驗目的:execl錯誤使用展示

編譯運作:

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

錯誤原因:execl的第一個參數不支援是相對路徑,是以上述實驗中execl的第一個參數應該是path2 .

實驗1

實驗目的1: execl使用展示

實驗目的2:

雖然exec系列函數執行成功不傳回,但是我們仍然要使用wait或waitpid讓父程序給該子程序收屍,否則将會産生一個僵屍程序(子程序死了,老爸沒給收屍,子成為僵屍)!

屏蔽父程序内的wait函數與否将産生不同的效果,可使用ps -aux檢視子程序是否變成了僵屍程序。

為了承接本文章上下文的連續性,将實驗1分為三個小實驗,逐漸加深了解。

實驗1-1: 驗證僵屍程序的産生

在一個終端内編譯運作:

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

可見,子程序的程序ID是21018, 我們來看看在父程序不回收子程序,而子程序内又使用execl執行完畢了新程式後,是否會産生僵屍程序吧!

在另一個終端内檢視:

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

實驗證明,子程序21018成為了僵屍程序。

同時,printf(“exec %s success\n”, elf_name)這句代碼未列印,由此,我們也可以看出,通過execl執行的新程式正常執行是不會傳回給主程式的,

實際上,通過整個exec系列函數成功執行新程式,都是不會傳回給主程式的。

然而,父程序fork了子程序後就要遵循給其收屍的原則,即使使用了exec系列函數,也是如此。

相關知識點補充 - 程序狀态及其辨別 :

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

實驗1-2

在實驗1-1的代碼基礎上,父程序fork子程序後增加wait函數的使用,以用于對子程序的回收。此時我們重複實驗1-1的操作過程,我們不會見到子程序成為僵屍程序。

 本實驗和1-1極其相似,故省略。

實驗1-3

hello.c :

exec.c:

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

通過實驗可見,可執行程式hello被成功執行起來了并且在5秒後退出(讀者可以自行設定為6秒或者7秒或者8秒...),

同時,主程序内的wait調用也在5秒後成功傳回(通過肉眼觀察代碼執行效果得出),表明在ecex函數裝載的新程式結束後,父程序就對其展開收屍動作了。

本1-3實驗可以進一步加深我們對fork exec wait等api進行混合使用的了解。

實驗2 

實驗目的:execvp使用展示( 本質和execl一樣,都是為了調用新程式去執行,隻是使用的方式不一樣而已 )

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

根據前面的介紹,exec後面的v表示argv,是以execvp有一個參數是char* argv[]. 後面的p表示path,且支援相對路徑,但是該相對路徑必須要在系統的環境表中,

Linux下檢視系統環境表中的路徑:

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

實驗3  system介紹,自己編寫功能更為強大的mysystem(自己手動調用exec系列函數可在需要時攜帶更多參數)。

系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制
系統程式設計-程式-exec系列函數超級詳解(帶各種實操代碼) 系統程式設計-程式-close-on-exec機制

.

/************* 社會的有色眼光是:博士生、研究所學生、大學生、工廠中的房間勞工; 重點大學高材生、普通院校、二流院校、野雞大學; 年薪百萬、五十萬、五萬; 這些都隻是帽子,可以失敗千百次,但我和社會都覺得,人隻要成功一次,就能換一頂帽子,隻是社會看不見你之前的失敗的帽子。 當然,換帽子決不是最終目的,走好自己的路就行。 杭州.大話西遊 *******/

繼續閱讀