在程序控制(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下的...