電子產(chǎn)業(yè)一站式賦能平臺(tái)

PCB聯(lián)盟網(wǎng)

搜索
查看: 74|回復(fù): 0
收起左側(cè)

嵌入式Linux:子進(jìn)程執(zhí)行新程序

[復(fù)制鏈接]

532

主題

532

帖子

3116

積分

四級(jí)會(huì)員

Rank: 4

積分
3116
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-10-4 08:00:00 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
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: d
  • 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)境變量的支持。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, R
  • filename:要執(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* Y
  • int 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+ `: r
  • int 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 M
  • path:可執(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 A
  • int 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 g
  • file:要執(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
    / a, x5 _8 v* |! J2 u6 n: R1 d

    # T9 A* c" Z0 `" Q+ A  }8 O# S點(diǎn)擊閱讀原文,更精彩~
  • 發(fā)表回復(fù)

    本版積分規(guī)則

    關(guān)閉

    站長(zhǎng)推薦上一條 /1 下一條


    聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表