|
bcjhj5tzw3164043740700.gif (60.41 KB, 下載次數(shù): 7)
下載附件
保存到相冊(cè)
bcjhj5tzw3164043740700.gif
2024-10-4 21:58 上傳
3 @2 \4 F+ H, c) N9 b6 l- Y- v
點(diǎn)擊上方藍(lán)色字體,關(guān)注我們
9 l& S( Z# Z' j( K! `8 w. I8 [- F8 k在 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è)變體,常見(jiàn)的有 execl()、execv()、execle()、execve() 等,它們的主要區(qū)別在于參數(shù)傳遞方式不同。
6 L$ k7 `; Z% C# g: Y5 a: K# l/ A* |, n; w
子進(jìn)程執(zhí)行新程序的流程如下:
" s$ o1 b+ Y Q6 H9 D6 }創(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é)束。
4 G- {5 `3 V: q, ~8 T$ g1 ?
6 a K3 E e% x1 Fexec 系列函數(shù)通過(guò)不同的方式傳遞參數(shù)和環(huán)境變量,能夠?qū)崿F(xiàn)靈活的程序替換。具體函數(shù)如下:
6 _# z' s7 n7 P: dexecve() 是最基礎(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)境變量的支持。1 T8 q* ~ F' \0 P
; S4 g9 ?) j: `( h+ p) V
1
+ \0 [4 ~/ q f8 ]execve()
A3 {, E# U- `/ Qexecve() 是最基礎(chǔ)的 exec 函數(shù),所有其他 exec 系列函數(shù)都是基于它的。它直接接受路徑名、參數(shù)數(shù)組和環(huán)境變量數(shù)組。
& y3 m& }; X( P* a- N/ E: g e- \8 L& I$ z1 P* U3 s! u8 F
函數(shù)原型如下:
3 @3 b0 a( X( C; }$ _4 [ q$ V& w: M. H* C: Q: b/ t: u
int execve(const char *filename, char *const argv[], char *const envp[]);6 Z8 H$ [3 X5 p I9 V$ f
參數(shù)如下:
# M3 g/ A: l4 J: x3 r, Rfilename:要執(zhí)行的文件的路徑(絕對(duì)或相對(duì)路徑)。argv[]:參數(shù)列表(傳遞給程序的命令行參數(shù))。第一個(gè)參數(shù)通常是程序本身的名稱(chēng)。envp[]:環(huán)境變量列表。1 J, D3 R" ^; R! b X' R2 u/ \6 v* h
- P M; r0 K9 C0 F& p( \' J
使用 execve() 執(zhí)行 /bin/ls,傳遞了參數(shù) -l 和環(huán)境變量 PATH。
" M9 Q h' Y/ x$ i8 |( ]2 Y& f) r2 W1 D T& j
#include #include #include int main(void) { char *argv[] = {"ls", "-l", NULL}; // 參數(shù)列表 char *envp[] = {"PATH=/bin", NULL}; // 環(huán)境變量 printf("執(zhí)行 ls 程序
7 y( t$ A9 v" g. N"); if (execve("/bin/ls", argv, envp) == -1) { perror("execve error"); } return 0;}9 N: x5 a4 K- X1 o) g! {
24 q8 I0 E" N! G6 w2 h/ G
execl()
" Z8 u) ~. a9 |# g6 J; bexecl() 是 execve() 的簡(jiǎn)化版本,參數(shù)以可變長(zhǎng)度的方式傳遞(列表形式)。最后一個(gè)參數(shù)必須是 (char *) NULL。
% L+ O7 C- ~# Z: t5 W. U+ |$ J% x% {- E# U! u8 K6 X+ v
函數(shù)原型如下:
$ Z6 ~! ^0 q, z( X) C- s
3 K1 z9 {- ^+ k: F; z* Yint execl(const char *path, const char *arg, ... /* (char *) NULL */);* D6 l5 [- d* S( p, q
參數(shù)如下:/ H* {9 s+ L- o8 ? F. D. h' |
path:可執(zhí)行文件的路徑。arg:程序名稱(chēng)后接任意數(shù)量的參數(shù),最后以 NULL 結(jié)束。% c) {; B' i* ~
" [( K- m, g N/ d6 P& h, }1 E
以下例子調(diào)用 execl(),通過(guò)可變參數(shù)傳遞給 ls 程序。
' Q& A7 G s5 B* v
% N+ m& N8 j/ |( W- I: X0 L5 u#include #include #include int main(void) { printf("使用 execl 執(zhí)行 ls 程序
) r2 \# X* _4 d# m' e"); execl("/bin/ls", "ls", "-l", (char *) NULL); // 傳遞可變長(zhǎng)度參數(shù)列表 // 如果 exec 調(diào)用失敗,返回 -1 perror("execl error"); return 0;}$ k# w- P O. u# y
3
5 I8 c$ ~6 k1 r8 P/ G" sexeclp()0 S- P1 q" S) p |6 m9 I( N
execlp() 和 execl() 類(lèi)似,但它不需要提供文件的完整路徑。它會(huì)在 PATH 環(huán)境變量指定的目錄中搜索可執(zhí)行文件。
7 o4 n3 V$ v; y
% y' H c* y) c& ?+ z$ |函數(shù)原型如下:
, i: k: N. s4 r+ s8 k) x, o
* b; t8 B. l6 D+ `: rint execlp(const char *file, const char *arg, ... /* (char *) NULL */);
0 h6 ]% z& j8 L7 `9 c+ {' q8 P5 j6 `參數(shù)如下:1 j0 O- y0 Y, v( d
file:要執(zhí)行的程序名(無(wú)需完整路徑)。arg:程序名稱(chēng)及其他參數(shù),最后以 NULL 結(jié)束。
/ z+ m' P1 L1 h* O/ P e( w9 m* y7 A+ [4 R9 h
以下例中,execlp() 會(huì)根據(jù) PATH 環(huán)境變量查找 ls 程序的路徑。" X A1 E. r' o( ]0 o
) S+ g4 {1 n. Y; y- `3 Q1 Z4 q#include #include #include int main(void) { printf("使用 execlp 執(zhí)行 ls 程序
( j) \9 Z# V- t0 {' A2 M( P"); execlp("ls", "ls", "-l", (char *) NULL); // 使用環(huán)境變量中的路徑搜索 ls 程序 perror("execlp error"); return 0;}
. K, V# [# _, U. O# i4& W8 p) L' n( A0 G
execle()
5 g7 Q. U% Z# [0 J/ wexecle() 類(lèi)似于 execl(),但允許傳遞環(huán)境變量數(shù)組。
- G. g* D0 F8 Q7 L
: ?, C- X3 g" o1 Q函數(shù)原型如下:
4 u: s2 M& t! {6 R. \+ R+ k3 P5 x4 w) T- J) h- v
int execle(const char *path, const char *arg, ... /*, (char *) NULL, char * const envp[] */);參數(shù)如下:
5 {2 D; `, W' R0 Mpath:可執(zhí)行文件路徑。arg:程序名稱(chēng)及其他參數(shù),最后以 NULL 結(jié)束。envp[]:環(huán)境變量數(shù)組。4 F/ N9 v5 s" Q
! ?5 X9 \) z$ c4 x! D1 N1 X; Y
以下例子中,execle() 將自定義的環(huán)境變量傳遞給 ls 程序。" v ?4 i, \6 G; A
F3 S9 F0 J$ S% c1 z
#include #include #include int main(void) { char *envp[] = {"PATH=/bin", NULL}; // 設(shè)置環(huán)境變量 printf("使用 execle 執(zhí)行 ls 程序% [5 `; t7 c% ~- n4 n- l/ o$ V
"); execle("/bin/ls", "ls", "-l", (char *) NULL, envp); // 傳遞環(huán)境變量 perror("execle error"); return 0;}
( Y1 u& F( r- |$ D7 M5
! j+ F) L" k6 ^. eexecv()
' P" ?- |6 T+ n+ m) I: sexecv() 是 execve() 的簡(jiǎn)化版本,不需要傳遞環(huán)境變量,只需要路徑和參數(shù)數(shù)組。
9 E3 l& L. Y: M! y ^! c6 `5 U7 }3 i' `8 s- z/ r- E
函數(shù)原型如下:
4 l) M' D/ b# H, A. X7 W. q
0 N% P0 m0 T7 M" W7 Aint execv(const char *path, char *const argv[]);
/ @8 [" E" T6 R參數(shù)如下:
) f: f5 a8 U8 {path:可執(zhí)行文件的路徑。argv[]:參數(shù)數(shù)組。$ P7 I8 @& b/ j8 r1 P. q# [
A l/ K: _. O2 A$ R( @在該例中,execv() 使用參數(shù)數(shù)組執(zhí)行 ls。! M9 J$ u5 n7 c7 ]0 p/ ]( Q' W7 N
* N' |, U, z2 c" H: P4 E
#include #include #include int main(void) { char *argv[] = {"ls", "-l", NULL}; // 參數(shù)數(shù)組 printf("使用 execv 執(zhí)行 ls 程序6 ]" l1 i' F4 B, ?
"); execv("/bin/ls", argv); // 傳遞參數(shù)數(shù)組 perror("execv error"); return 0;}1 ~# \/ Y- c/ _. q
6
- X D% Q7 n" x9 bexecvp()
4 ?1 s* _- x, ^2 |execvp() 和 execv() 類(lèi)似,但它會(huì)根據(jù) PATH 環(huán)境變量查找可執(zhí)行文件。
4 P) n5 ?9 E: ?( w! x
5 { P: _& c9 J/ O' X6 t函數(shù)原型如下:( U4 C4 y* V% m3 o3 d! k& P9 n
$ }3 Q( o; \8 d: J: D6 }int execvp(const char *file, char *const argv[]);
& ?/ ^. K3 ?3 \5 J- R0 B$ V參數(shù)如下:. ~% T; [: C+ c( j! d8 L9 C
file:可執(zhí)行文件的名稱(chēng)。argv[]:參數(shù)數(shù)組。
5 K, w/ V$ E9 i1 ^# S' V8 n3 {
' k; I0 t7 h9 h! Eexecvp() 不要求完整路徑,會(huì)自動(dòng)在 PATH 中查找 ls。
! i' V$ c$ i8 g
% f3 P. S( L5 c- U8 i7 ]: i0 d#include #include #include int main(void) { char *argv[] = {"ls", "-l", NULL}; // 參數(shù)數(shù)組 printf("使用 execvp 執(zhí)行 ls 程序 M& l3 j7 A/ V; n9 ]6 P
"); execvp("ls", argv); // 根據(jù) PATH 搜索并執(zhí)行程序 perror("execvp error"); return 0;}) B) V3 }( F( }( x: m0 y2 r7 A
7) e' U4 M' D: u6 C: o5 [
execvpe()
; p9 a8 Y$ _! h* ^/ m6 N6 O) P/ kexecvpe() 是 execvp() 的擴(kuò)展,允許傳遞自定義的環(huán)境變量。& l- j. z7 M4 Z. m; e7 ^2 u
( E5 A1 m$ m% c6 Q5 [# W% u
函數(shù)原型如下:6 r' S" s7 \4 L0 l l8 i
3 n2 H- G8 W- C! V! x* p
int execvpe(const char *file, char *const argv[], char *const envp[]);
: s' G4 \$ n5 E4 |" l9 H1 ~) V$ e參數(shù)如下:
! z I' m" n5 Q6 o9 X; I0 gfile:要執(zhí)行的程序名稱(chēng)。argv[]:參數(shù)數(shù)組。envp[]:環(huán)境變量數(shù)組。3 s$ m9 m8 ]0 Y. V+ E; @1 {
4 E7 Q1 @5 R u% G- g7 T9 p& y$ Q在以下示例中,execvpe() 使用自定義環(huán)境變量執(zhí)行程序。
( N5 b8 [6 M& |4 \( O+ `) r7 x. B& B7 c1 t; B1 G# ?4 f2 V8 q
#include #include #include int main(void) { char *argv[] = {"ls", "-l", NULL}; // 參數(shù)數(shù)組 char *envp[] = {"PATH=/bin", NULL}; // 環(huán)境變量 printf("使用 execvpe 執(zhí)行 ls 程序1 o* K: D: {6 W$ ^& y
"); execvpe("ls", argv, envp); // 使用 PATH 環(huán)境變量執(zhí)行程序 perror("execvpe error"); return 0;}
- W$ m6 ~% F: P+ u1 w子進(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)程的靈活控制。
7 D$ O* g3 x1 H( u6 r2 }( x# z% E) W7 b8 T
10xbnqwm4sa64043740800.jpg (71.14 KB, 下載次數(shù): 6)
下載附件
保存到相冊(cè)
10xbnqwm4sa64043740800.jpg
2024-10-4 21:58 上傳
/ a, x5 _8 v* |! J2 u6 n: R1 d
kedsigagli564043740900.gif (45.46 KB, 下載次數(shù): 7)
下載附件
保存到相冊(cè)
kedsigagli564043740900.gif
2024-10-4 21:58 上傳
# T9 A* c" Z0 `" Q+ A }8 O# S點(diǎn)擊閱讀原文,更精彩~ |
|