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

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

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

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

[復(fù)制鏈接]

660

主題

660

帖子

4567

積分

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

Rank: 4

積分
4567
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-10-4 08:00:00 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式

; {% 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/ |) k
  • filename:要執(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 ?" X
  • int execl(const char *path, const char *arg, ... /* (char *) NULL */);
    . a) }) Z' ~& U; d0 }! q參數(shù)如下:
    ' Z; M' S! @% ^) m5 g4 q/ @4 l
  • path:可執(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 o
  • int execle(const char *path, const char *arg, ... /*, (char *) NULL, char * const envp[] */);參數(shù)如下:
    - n; s' P9 Y: {7 l: z2 Z1 y8 q. v
  • path:可執(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 \: j
  • int 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 Y
  • file:要執(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 ' Q+ }7 X, [% S8 s% d
    ' K$ y* A/ W3 E
    點(diǎn)擊閱讀原文,更精彩~
  • 發(fā)表回復(fù)

    本版積分規(guī)則


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