exec()函數(shù)在C++中的應用及其用法
前言
fork
函數(shù)之后,如果想要把子進程換成一個我想要執(zhí)行的進程,這時,就不得不使用 exec()
函數(shù)了,這也是 fork()
的意義所在。當然,exec
系列的函數(shù)也可以將當前進程替換掉,不一定非要 fork()
一個子進程。常見的 fork()
調(diào)用例子有很多,比如從 wechat
發(fā)起一個語音電話、從 bash
或者zsh
執(zhí)行一個 a.out
程序,都是在利用exec
系統(tǒng)調(diào)用將新產(chǎn)生的子進程完全替換成目標進程。
比如,這是一個死循環(huán)程序(目的是為了觀察,讓它活得久一點):
#include <stdio.h> int main() { int a = 0; while (1) { a++; } return 0; }
通過編譯,執(zhí)行:
gcc fork_example.c -o fork_example
./fork_example
查看進程:top
可以發(fā)現(xiàn),fork_example的進程的 PPID 為 54861,我們看看它是誰:ps 54861
PID TT STAT TIME COMMAND
54861 s018 Ss 0:00.23 /bin/zsh -il
很明顯,它是 zsh
,現(xiàn)在可以終止fork_example: kill 57892
zsh: terminated ./fork_example
程序就會結(jié)束!以上例子,可以看到我們的子進程,就是由一個父進程 fork()
之后替換的。
exec()
#include<unistd.h>
原型:
int execl(const char *path, const char *arg, ...) int execv(const char *path, char *const argv[]) int execle(const char *path, const char *arg, ..., char *const envp[]) int execve(const char *path, char *const argv[], char *const envp[]) int execlp(const char *file, const char *arg, ...) int execvp(const char *file, char *const argv[])
參數(shù):
path
參數(shù)表示你要啟動程序的名稱,包括路徑名;
arg
參數(shù)表示啟動程序所帶的參數(shù),一般第一個參數(shù)為要執(zhí)行命令名
返回值:成功返回0,失敗返回-1
上述exec系列函數(shù)底層都是通過execve系統(tǒng)調(diào)用實現(xiàn):
#include <unistd.h>int execve(const char *filename, char *const argv[],char *const envp[]);#include <unistd.h> int execve(const char *filename, char *const argv[],char *const envp[]);
① 查找方式:上表其中前4個函數(shù)的查找方式都是完整的文件目錄路徑,而最后2個函數(shù)(也就是以p結(jié)尾的兩個函數(shù))可以只給出文件名,系統(tǒng)就會自動從環(huán)境變量“$PATH”
所指出的路徑中進行查找。
② 參數(shù)傳遞方式:exec
函數(shù)族的參數(shù)傳遞有兩種方式,一種是逐個列舉的方式,而另一種則是將所有參數(shù)整體構(gòu)造成指針數(shù)組進行傳遞。
在這里參數(shù)傳遞方式是以函數(shù)名的第5位字母來區(qū)分的,字母為“l”(list)的表示逐個列舉的方式,字母為“v”(vertor)的表示將所有參數(shù)整體構(gòu)造成指針數(shù)組傳遞,然后將該數(shù)組的首地址當做參數(shù)傳給它,數(shù)組中的最后一個指針要求是NULL。讀者可以觀察execl、execle、execlp的語法與execv、execve、execvp的區(qū)別。
③ 環(huán)境變量:exec函數(shù)族使用了系統(tǒng)默認的環(huán)境變量,也可以傳入指定的環(huán)境變量。這里以“e”(environment)結(jié)尾的兩個函數(shù)execle、execve
就可以在envp[]
中指定當前進程所使用的環(huán)境變量替換掉該進程繼承的所以環(huán)境變量,這極大地提供了靈活度。
execl()
該函數(shù)的定義為:
int execl(const char *path, const char *arg, ...)
可以看到,它的參數(shù)為一個 path
,由于不帶 p
,因此,最后一個參數(shù)為 NULL
。
例如:
#include <stdio.h> #include <unistd.h> int main() { printf("hello!\n"); // 替換 main 進程 execl("/bin/ls", "ls", "-a", NULL); // good bye! 并不會被打印出來 printf("good bye!\n"); return 0; }
執(zhí)行結(jié)果:
hello!
. a.out execlp.c fork_example myshell.c
.. execl.c fork.c fork_example.c
可以看到,它成功地執(zhí)行了"ls -a"
命令。
execlp()
該函數(shù)的定義為:
int execlp(const char *file, const char *arg, ...)
該函數(shù)帶 p
,第一個參數(shù)是一個 *file
,說明不需要帶完整路徑,它會在默認環(huán)境變量里面自動查找:
#include <stdio.h> #include <unistd.h> int main() { printf("hello!\n"); // 替換 main 進程 execl("ls","ls", "-a", NULL); // good bye! 并不會被打印出來 printf("good bye!\n"); return 0; }
運行結(jié)果:
hello!
good bye!
說明,并沒有成功替換,這是我們帶個 p:
#include <stdio.h> #include <unistd.h> int main() { printf("hello!\n"); // 替換 main 進程 execlp("ls","ls", "-a", NULL); // good bye! 并不會被打印出來 printf("good bye!\n"); return 0; }
運行結(jié)果:
hello!
. a.out execlp.c fork_example myshell.c
.. execl.c fork.c fork_example.c
成功替換!其它的函數(shù)也是同理,就不再贅述了。
到此這篇關(guān)于exec()函數(shù)在C++中的應用及其用法的文章就介紹到這了,更多相關(guān)C++ exec()函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言實現(xiàn)職工工資管理系統(tǒng)的示例代碼
這篇文章主要為大家詳細介紹了C語言如何實現(xiàn)職工工資管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-08-08三種獲取網(wǎng)頁源碼的方法(使用MFC/Socket實現(xiàn))
Windows下比較簡單的獲取網(wǎng)頁源碼的方法:使用MFC、使用MFC、Socket實現(xiàn)2013-12-12C++?string如何獲取文件路徑文件名、文件路徑、文件后綴(兩種方式)
這篇文章主要介紹了C++?string如何獲取文件路徑文件名、文件路徑、文件后綴(兩種方式),具有很好的參考價值,希望對大家有所幫助。2023-06-06