程序控制(2)

2021-08-21 10:11:04 字數 4371 閱讀 4762

在程序控制(1)中,介紹了建立子程序fork和vfork函式,其實在建立乙個程序之後,子程序往往會呼叫乙個exec函式去執行另乙個程式。當呼叫乙個exec函式之後,該程序執行的程式完全替換為新程式,而新程式從main函式開始執行。exec函式並不建立新的程序,前後程序id不變,只是用磁碟上的乙個新程式替換了當前程序的正文段、資料段、堆段和棧段。

exec函式

#include 

int execl(const

char *pathname, const

char *arg0, ... /* (char *)0 */);

int execv(const

char *pathname, char *const argv);

int execle(const

char *pathname, const

char *arg0, ... /* (char *)0, char *const envp */);

int execve(const

char *pathname, char *const argv, char *const envp);

int execlp(const

char *filename, const

char *arg0, ... /* (char *)0 */);

int execvp(cosnt char *filename, char *const argv);

6個函式的返回值:若出錯則返回-1,若成功則沒有返回值,其中只有execve函式屬於核心的系統呼叫,其他的只是庫函式

這六個函式中只有execve函式屬於核心的系統呼叫,其他的只是庫函式,這幾個函式之間的關係可以表示為下圖:

下面給出幾個具體的例子來說明這幾個函式的用法:

1、使用execl和execv來傳遞引數

#include "apue.h"

int main(int argc, char *argv)

exit(0);

}

生成上面程式的可執行檔案後,在demo中用使用execl和execv。

#include"apue.h"

#include

char demopath = "/home/xucheng/xc/test/print";

char *myargs = ;

intmain(void)

else

if (pid == 0)

} if(waitpid(pid,null,0)<0)

err_sys("wait error");

if ((pid = fork()) < 0) else

if (pid == 0)

} if(waitpid(pid,null,0)<0)

err_sys("wait error");

exit(0);

}

執行的結果為:

xucheng@xucheng-inspiron-5520

:~/xc/test

$ gcc demo.c -o demo

xucheng@xucheng-inspiron-5520

:~/xc/test

$ ./demo

transmits by vector

arg1: xucheng

arg2: ha

arg3: ha

arg4: ha

transmits by list

arg1: print

arg2: xucheng

arg3: ha

arg4: ha

arg5: ha

需要特別說明一點,在呼叫 execl、execle 和 execlp 函式傳遞參數列,在最後乙個命令列引數之後跟著乙個空指標。如果要用常量 0 來表示空指標,則必須要將它轉換為乙個字元指標。

2、使用帶有環境變數的exec函式

以e結尾的3個函式可以傳遞乙個指向環境字串指標陣列的指標。

下面這個函式會列印出所有的環境字串。

#include"apue.h"

int main(void)

exit(0);

}

編譯執行後,可以看到:

xucheng@xucheng-inspiron-5520

:~/xc/test

$ ./print

xdg_vtnr=7

lc_*****=zh_cn.utf-8

lc_address=zh_cn.utf-8

xdg_session_id=c2

xdg_greeter_data_dir=/var/lib

/lightdm-data/xucheng

lc_monetary=zh_cn.utf-8

......

下面在demo中使用execv函式和execve函式,呼叫上面生成的可執行檔案,比較列印的環境變數列表有何區別。

#include"apue.h"

#include

char demopath = "/home/xucheng/xc/test/print";

char *myenvs = ;

int main(void)

if ((pid = fork()) < 0) else

if (pid == 0)

} if(waitpid(pid,null,0)<0)

err_sys("wait error");

if ((pid = fork()) < 0) else

if (pid == 0)

} if(waitpid(pid,null,0)<0)

err_sys("wait error");

exit(0);

}

執行結果如下:

xucheng@xucheng-inspiron-5520:~/xc/test$ ./demo 

print_envir by execv

xdg_vtnr=7

lc_*****=zh_cn.utf-8

lc_address=zh_cn.utf-8

......

xauthority=/home/xucheng/.xauthority

oldpwd=/home/xucheng

_=./demo

newenv=add in parent process

print_envir by execve

env1=hhhhhh

env2=aaaaaaa

從上面的執行結果,我們看到呼叫 execv 函式時父程序會將其設定的環境變數也傳遞給了子程序。而呼叫execve 函式時,子程序的環境變數列表只有 execve 函式傳遞的 列表。

#! pathname[optional-argument]
核心使呼叫exec函式的程序實際執行的不是該直譯器檔案,而是在該直譯器檔案中第一行pathname中所指定的檔案。如下:

#include "apue.h"

#include

intmain(void)

else

if (pid == 0)

if (waitpid(pid, null, 0) < 0) /* parent */

err_sys("waitpid error");

exit(0);

}

執行之前要更該直譯器檔案的許可權,執行之後,結果為:

xucheng@xucheng-inspiron-5520

:~/xc/test

$ cat temp

#! /home/xucheng/xc/test/print foo

xucheng@xucheng-inspiron-5520

:~/xc/test

$ ./demo

arg0: /home/xucheng/xc/test/print

arg1: foo

arg2: /home/xucheng/xc/test/temp

arg3: myarg1

arg4:

myarg2

其中argv[0]是直譯器檔案的pathname,argv[1]是直譯器檔案中的可選引數。

linux 程序控制2

在程序控制的章節我們講解了我們的程序建立,這章節對程序控制進行補充,在我們建立乙個程序之後我們避免不了我們去終止我們的程序。終止場景 終止方式 include void exit int status include void exit int status 雖然兩個函式都是可以讓程序終止的,但是兩...

unix linux多程序程式設計2 程序控制

主要內容 程序建立 執行程式 程序終止 程序屬性 1 程序識別符號 1.1 每個程序都有乙份非負整數表示的唯一程序id 程序id可以重新,乙個程序結束之後可以,這個id可以被其他程序所使用,當unix普遍都採用了延遲重用演算法。使得某乙個程序結束之後其id不會馬上被新的程序所使用,以防止將新程序誤認...

程序及程序控制

學習程序之前,先了解一下程式 所謂程式就是指編譯好的二進位制檔案,在磁碟上,不占用系統資源 cpu 記憶體.而程序是與作業系統相關,是指在記憶體中執行起來的程式,占用一些系統資源,每當乙個程式執行,就相應產生乙個程序。程序的一些相關資訊被放在乙個叫程序控制塊的資料結構中,稱之為pcb。linux下的...