|
bcjhj5tzw3164043740700.gif (60.41 KB, 下載次數(shù): 8)
下載附件
保存到相冊(cè)
bcjhj5tzw3164043740700.gif
2024-10-4 21:58 上傳
; {% v' r" } m0 k5 V5 ?點(diǎn)擊上方藍(lán)色字體,關(guān)注我們
, k8 a+ v6 X" t) P' d) j5 J( O1 Q在 Linux 中,子進(jìn)程在創(chuàng)建后可以通過(guò) exec 系列系統(tǒng)調(diào)用執(zhí)行一個(gè)全新的程序。這種情況下,子進(jìn)程會(huì)替換原有的代碼和數(shù)據(jù)段,運(yùn)行一個(gè)新的可執(zhí)行程序,但它的進(jìn)程 ID(PID)保持不變。exec 系列調(diào)用包括多個(gè)變體,常見的有 execl()、execv()、execle()、execve() 等,它們的主要區(qū)別在于參數(shù)傳遞方式不同。
# ]' d1 K: I; Z1 O
# w0 I. Z, [8 L- r! q) }. O- @子進(jìn)程執(zhí)行新程序的流程如下:3 R# i, j9 [( f* k
創(chuàng)建子進(jìn)程:使用 fork() 創(chuàng)建子進(jìn)程。調(diào)用 exec:在子進(jìn)程中調(diào)用 exec 執(zhí)行新程序。替換子進(jìn)程的內(nèi)存映像:exec 會(huì)替換子進(jìn)程的整個(gè)內(nèi)存空間,包括代碼段、數(shù)據(jù)段、堆棧等,只保留進(jìn)程的 PID 和一些特定屬性。父進(jìn)程繼續(xù)執(zhí)行:父進(jìn)程保持不變,繼續(xù)執(zhí)行它的代碼,直到調(diào)用 wait() 等待子進(jìn)程結(jié)束。
) \3 d* e, B( _2 [
M5 i$ H. ~1 X- _- E" x% Qexec 系列函數(shù)通過(guò)不同的方式傳遞參數(shù)和環(huán)境變量,能夠?qū)崿F(xiàn)靈活的程序替換。具體函數(shù)如下:" n' V$ Z$ w$ x, D5 i5 Q
execve() 是最基礎(chǔ)的調(diào)用,允許自定義環(huán)境變量和參數(shù)。execl() 和 execv() 提供了簡(jiǎn)化接口,execl() 使用可變參數(shù),execv() 使用參數(shù)數(shù)組。execlp() 和 execvp() 可以根據(jù) PATH 環(huán)境變量搜索程序。execle() 和 execvpe() 提供自定義環(huán)境變量的支持。* @) E9 Q6 Z1 D/ {7 X. d
* w+ J1 I3 f/ B+ D b1+ b' k: k5 a+ z5 a& `" E% V
execve()
4 V& ?4 K3 o3 b' ]% \+ s/ Oexecve() 是最基礎(chǔ)的 exec 函數(shù),所有其他 exec 系列函數(shù)都是基于它的。它直接接受路徑名、參數(shù)數(shù)組和環(huán)境變量數(shù)組。
4 l: S6 H& p+ b# p r
7 Y q4 t$ Z: J' ~8 T" L0 L9 V函數(shù)原型如下:
2 c. B& k1 D: w; v; O+ |* T _. Q
int execve(const char *filename, char *const argv[], char *const envp[]);+ e) {0 [' ?6 B& R& T
參數(shù)如下:
# S( a3 v8 J3 l/ |) kfilename:要執(zhí)行的文件的路徑(絕對(duì)或相對(duì)路徑)。argv[]:參數(shù)列表(傳遞給程序的命令行參數(shù))。第一個(gè)參數(shù)通常是程序本身的名稱。envp[]:環(huán)境變量列表。$ ?9 c; G, L* y7 _5 v
7 r# @* Y0 ^& L# a! u& J9 ^
使用 execve() 執(zhí)行 /bin/ls,傳遞了參數(shù) -l 和環(huán)境變量 PATH。
9 V3 `& o) l3 q# b5 q. k
( Q& U) [( z n8 G& F% g/ X#include #include #include int main(void) { char *argv[] = {"ls", "-l", NULL}; // 參數(shù)列表 char *envp[] = {"PATH=/bin", NULL}; // 環(huán)境變量 printf("執(zhí)行 ls 程序& h* b; l [6 ?8 {- N5 s, O
"); if (execve("/bin/ls", argv, envp) == -1) { perror("execve error"); } return 0;}
. u; x$ D6 S, P0 H. [- E2
* [' | c# Z. y t4 Z2 xexecl()4 J; c; f5 ^8 }* B" y& }
execl() 是 execve() 的簡(jiǎn)化版本,參數(shù)以可變長(zhǎng)度的方式傳遞(列表形式)。最后一個(gè)參數(shù)必須是 (char *) NULL。
+ C: O2 r I# M2 ~. X% \# T2 x Y+ f8 W
7 \+ R) X- q5 B7 ~' l, z4 B5 G函數(shù)原型如下:# F) L1 e# r/ R1 L; Q q! F
0 [% A M! f: h7 ?" Xint execl(const char *path, const char *arg, ... /* (char *) NULL */);
. a) }) Z' ~& U; d0 }! q參數(shù)如下:
' Z; M' S! @% ^) m5 g4 q/ @4 lpath:可執(zhí)行文件的路徑。arg:程序名稱后接任意數(shù)量的參數(shù),最后以 NULL 結(jié)束。! M* l& c+ V0 s: O
; r Q+ F' K& X6 u6 Q# h, B2 e h以下例子調(diào)用 execl(),通過(guò)可變參數(shù)傳遞給 ls 程序。! N3 S3 ~1 U, r- v9 i8 u8 f
3 U/ i' W" ?( }; v( P#include #include #include int main(void) { printf("使用 execl 執(zhí)行 ls 程序" m8 B- @/ E6 R
"); execl("/bin/ls", "ls", "-l", (char *) NULL); // 傳遞可變長(zhǎng)度參數(shù)列表 // 如果 exec 調(diào)用失敗,返回 -1 perror("execl error"); return 0;}
: r0 N/ i& j( F) C) M U38 F" ~$ A% G, {
execlp()
/ _% r; B; g0 d# k! bexeclp() 和 execl() 類似,但它不需要提供文件的完整路徑。它會(huì)在 PATH 環(huán)境變量指定的目錄中搜索可執(zhí)行文件。 {' z# e8 Y x2 r% s- }
2 r7 ~4 Z5 p1 w% D
函數(shù)原型如下:# {' V: P1 m( M; Z _' x
; f; V+ _# Y6 s! c. g s
int execlp(const char *file, const char *arg, ... /* (char *) NULL */);& ~3 Q! |8 z* P: ?
參數(shù)如下:1 [( u1 V8 H/ [7 z& ^$ m
file:要執(zhí)行的程序名(無(wú)需完整路徑)。arg:程序名稱及其他參數(shù),最后以 NULL 結(jié)束。% g! T) S" L* n8 V
% ~( o" A$ X, L7 ?以下例中,execlp() 會(huì)根據(jù) PATH 環(huán)境變量查找 ls 程序的路徑。3 i! ^9 j1 M5 o. e
$ P! e4 ?. W8 S2 Z+ h) H#include #include #include int main(void) { printf("使用 execlp 執(zhí)行 ls 程序
" b8 m N8 g1 Q4 Q"); execlp("ls", "ls", "-l", (char *) NULL); // 使用環(huán)境變量中的路徑搜索 ls 程序 perror("execlp error"); return 0;}
) @5 j7 P$ P: t4) I" ]3 b3 d, V& Y' U" r+ [9 c+ t
execle(), E+ m4 w. A, T
execle() 類似于 execl(),但允許傳遞環(huán)境變量數(shù)組。
" ?7 r3 F6 l( B& G2 N9 J7 ^1 n0 f
函數(shù)原型如下:
3 f: A c7 {( [# k- W: x" @( m9 x& P
' M. v& N7 {* }7 oint execle(const char *path, const char *arg, ... /*, (char *) NULL, char * const envp[] */);參數(shù)如下:
- n; s' P9 Y: {7 l: z2 Z1 y8 q. vpath:可執(zhí)行文件路徑。arg:程序名稱及其他參數(shù),最后以 NULL 結(jié)束。envp[]:環(huán)境變量數(shù)組。
4 `& Y1 D: u2 [' a& }7 D0 |0 w$ Z
7 T5 \) g. h f3 ~$ q+ c# y# {以下例子中,execle() 將自定義的環(huán)境變量傳遞給 ls 程序。" W# [7 j: e( o
/ }1 B; X+ C k+ }) w
#include #include #include int main(void) { char *envp[] = {"PATH=/bin", NULL}; // 設(shè)置環(huán)境變量 printf("使用 execle 執(zhí)行 ls 程序
: }; @9 E# Z2 \/ O0 |* f2 x$ N9 o+ ?"); execle("/bin/ls", "ls", "-l", (char *) NULL, envp); // 傳遞環(huán)境變量 perror("execle error"); return 0;}5 E7 B5 f4 V% Z! ^
5
* t; _' b: x$ e# g& @execv()
* P/ `; L Q2 R% U9 d! K9 Yexecv() 是 execve() 的簡(jiǎn)化版本,不需要傳遞環(huán)境變量,只需要路徑和參數(shù)數(shù)組。* g+ @1 g( j; k, l
4 }6 @& R: G! D0 u9 p8 y( f/ @ V
函數(shù)原型如下:0 l. L' X% a; M9 h, |6 p
) i( d; ~, u/ y1 }0 u7 ?6 E f
int execv(const char *path, char *const argv[]);
% |2 q) ]: b& L) \: S" L參數(shù)如下:0 e, b8 w- _, w/ F6 I" L
path:可執(zhí)行文件的路徑。argv[]:參數(shù)數(shù)組。
3 U, N% K `* x0 e
' F4 [- Z/ F7 S在該例中,execv() 使用參數(shù)數(shù)組執(zhí)行 ls。
, K3 W3 i3 y; u f$ c" h$ c! E1 b {0 W, g) u5 h* O
#include #include #include int main(void) { char *argv[] = {"ls", "-l", NULL}; // 參數(shù)數(shù)組 printf("使用 execv 執(zhí)行 ls 程序
2 \9 [1 q+ u# T( J% ]"); execv("/bin/ls", argv); // 傳遞參數(shù)數(shù)組 perror("execv error"); return 0;}% z3 z2 _3 x7 q+ o# l& l7 c4 Z
6' b7 t0 d; g% m
execvp()% [8 h/ z/ M+ J) \$ p+ n# D: J
execvp() 和 execv() 類似,但它會(huì)根據(jù) PATH 環(huán)境變量查找可執(zhí)行文件。
+ }. X0 h5 ^7 C" g* P6 |
; W+ G _( l$ ~ a函數(shù)原型如下:
; e; j, F" n& C$ |2 l( x& m
3 X8 y2 g' u- E% s$ o0 \: jint execvp(const char *file, char *const argv[]);; O' ?" c# a) _6 C
參數(shù)如下:+ C. G" \* A. B. E& J# a' C
file:可執(zhí)行文件的名稱。argv[]:參數(shù)數(shù)組。
* i; L, ~5 ]( D' q: `2 N2 U' g" f9 p6 Z
execvp() 不要求完整路徑,會(huì)自動(dòng)在 PATH 中查找 ls。, v4 U) `& k5 U+ S1 G( b6 v
' U) Z2 Q6 W) Y. B/ C8 ^8 u9 k#include #include #include int main(void) { char *argv[] = {"ls", "-l", NULL}; // 參數(shù)數(shù)組 printf("使用 execvp 執(zhí)行 ls 程序1 r* b2 j% e) {7 b* k: g* G+ J
"); execvp("ls", argv); // 根據(jù) PATH 搜索并執(zhí)行程序 perror("execvp error"); return 0;}
6 Q% S. F$ M0 Q+ o0 J, I7
, Y5 U1 c, n& m) a7 j" U Nexecvpe()' ?7 O9 s0 S# N+ _% Q, k
execvpe() 是 execvp() 的擴(kuò)展,允許傳遞自定義的環(huán)境變量。# {* S, ? S6 L
3 {& T% \( Q! I* f* {( m
函數(shù)原型如下:
0 F1 a" R7 S2 u7 H. _4 T1 r$ f& J* Y& A0 y, e- ?4 V& k$ c
int execvpe(const char *file, char *const argv[], char *const envp[]);
9 M8 E& X& m' [5 Y) e( l* ^5 O: Z參數(shù)如下:
R& }# Q+ b, Y# [7 Yfile:要執(zhí)行的程序名稱。argv[]:參數(shù)數(shù)組。envp[]:環(huán)境變量數(shù)組。
" s, l, i! x, p- b) G3 ^; I0 H! x2 K2 h8 ]
在以下示例中,execvpe() 使用自定義環(huán)境變量執(zhí)行程序。; ?; z# h+ d- o" V7 z
! ^$ a# @3 _8 n2 U5 N2 @1 O#include #include #include int main(void) { char *argv[] = {"ls", "-l", NULL}; // 參數(shù)數(shù)組 char *envp[] = {"PATH=/bin", NULL}; // 環(huán)境變量 printf("使用 execvpe 執(zhí)行 ls 程序% e0 x+ [$ N2 ^+ ^( ^6 |. t# n/ l
"); execvpe("ls", argv, envp); // 使用 PATH 環(huán)境變量執(zhí)行程序 perror("execvpe error"); return 0;}# U8 P6 t8 p) j) D6 t* ~- O8 C8 X
子進(jìn)程執(zhí)行新程序時(shí),可以通過(guò) exec 系列系統(tǒng)調(diào)用替換子進(jìn)程的內(nèi)存空間,執(zhí)行新的二進(jìn)制程序。exec 系列調(diào)用的不同變體提供了靈活的參數(shù)傳遞方式,適應(yīng)不同場(chǎng)景需求。通過(guò)合理使用 fork() 和 exec(),可以實(shí)現(xiàn)高效的多進(jìn)程編程,確保資源的有效利用和進(jìn)程的靈活控制。
2 K9 C9 [2 i7 N6 x: O; n7 y2 N) P
( M. l6 c- G5 [* X
10xbnqwm4sa64043740800.jpg (71.14 KB, 下載次數(shù): 7)
下載附件
保存到相冊(cè)
10xbnqwm4sa64043740800.jpg
2024-10-4 21:58 上傳
' Q+ }7 X, [% S8 s% d
kedsigagli564043740900.gif (45.46 KB, 下載次數(shù): 8)
下載附件
保存到相冊(cè)
kedsigagli564043740900.gif
2024-10-4 21:58 上傳
' K$ y* A/ W3 E
點(diǎn)擊閱讀原文,更精彩~ |
|