2014025627 《嵌入式程序設計》第五周學習總結
教材學習內容總結
fork()函數:
一個進程,包括代碼、數據和分配給進程的資源。fork()函數通過系統調用創建一個與原來進程幾乎完全相同的進程,也就是兩個進程可以做完全相同的事,但如果初始參數或者傳入的變量不同,兩個進程也可以做不同的事。 一個進程調用fork()函數後,系統先給新的進程分配資源,例如存儲數據和代碼的空間。然後把原來的進程的所有值都復制到新的新進程中,只有少數值與原來的進程的值不同。fork()函數從已存在的進程中創建一個新進程。父進程→子進程,子進程幾乎是父進程的復制,其所獨有的只有它的進程號、資源使用和計時器等。子進程繼承了父進程的整個地址空間,包括進程上下文、代碼段、進程堆棧等。
Exec族函數
說是exec系統調用,實際上在Linux中,並不存在一個exec()的函數形式,exec指的是一組函數,一共有6個,分別是:
#include <unistd.h> int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg, ..., char *const envp[]); int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execve(const char *path, char *const argv[], char *const envp[]);
|
其中只有execve是真正意義上的系統調用,其它都是在此基礎上經過包裝的庫函數。exec函數族的作用是根據指定的文件名找到可執行文件,並用它來取代調用進程的內容,換句話說,就是在調用進程內部執行一個可執行文件。這裏的可執行文件既可以是二進制文件,也可以是任何
註意一定要寫上錯誤判斷語句,常見的錯誤有: 找不到文件或者路徑,此時error被設置為ENOENT;數組argv和envp忘記用NULL結束,此時error被設置為EFAUTL; 沒有對應可執行文件的運行權限,此時error被設置為EACCES;
execlp(),以文件名的方式來查找可執行文件,同時使用參數列表的方式。運行結果與在shell中輸入命令ps -ef是一樣的。 execl(),使用完整的文件目錄來查找對應的可執行文件。註意目錄必須以/開頭,否則將其視為文件名。if((execlp("/bin/ps","ps","-ef",NULL))<0) 這裏必須是ps程序的完整路徑,註意目錄必須以/開頭。
execle()函數將環境變量添加到新建的子進程中,這裏的env是查看當前進程環境變量的命令。命令參數列表,必須以NULL結尾 char *envp[]={"PATH=/tmp","USER=harry",NULL};if((execle("/usr/bin/env","env",NULL,envp))<0)需要指出env的完整路徑
execve()函數,通過構造指針函數數組的方式來傳遞函數,註意參數列表一定要以NULL作為結束標識符。
終止程序函數exit()和_exit()函數:
_exit()函數:直接使進程停止運行,清除其使用的內存空間,並銷毀其在內核中的各種數據結構;_exit()函數的作用是直接使進程停止運行,使文件讀寫的速度加快;而exit()函數先會“清理I/O緩沖”,若想要保證數據的完整性,最好使用exit()函數。
void _exit(int status); status用於傳遞進程結束的狀態,一般來說,0表示正常結束,其他數值表示非正常結束。 實際編程時,可以用wait()系統調用接收子進程的返回值,從而針對不同的情況進行不同的處理。
exit()函數則在這些基礎上作了一些包裝,在執行退出之前加了若幹道工序。
exit()函數與_exit()函數最大的區別就在於 exit()函數在調用 exit 系統調用之前要檢查文件的打開情況,把文件緩沖區中的內容寫回文件。
wait()函數和waitpid( )函數:
wait()函數用於使父進程(也就是調用wait()的進程)阻塞,直到一個子進程結束或者該進程接收到了一個指定的信號為止。如果父進程沒有子進程或者它的子進程已經結束,則wait()會立即返回-1. wait()會暫時停止目前進程的執行,直到有信號來到或子進程結束。如果在調用wait()時子進程已經結束,則wait()會立即返回子進程結束狀態值。子進程的結束狀態值會由參數status 返回,而子進程的進程識別碼也會一快返回
wait()函數的語法:
#include<sys/types.h>
#include<sys/wait.h>
pid_wait (int *status);
status指向的整型對象用來保存子進程結束時的狀態; 若成功則返回回收的子進程的進程號,失敗則返回-1;
waitpid()的作用與wait()一樣,但它並不一定等待第一個終止的子進程。waitpid()有若幹選項,可提供一個非阻塞版本的wait()功能。實際上,wait()只是 waitpid()函數的一個特例,在linux內部實現wait()函數時直接調用的就是waitpid()函數。waitpid()會暫時停止目前進程的執行,直到有信號來到或子進程結束。如果在調用 waitpid()時子進程已經結束,則 waitpid()會立即返回子進程結束狀態值。 子進程的結束狀態值會由參數 status 返回,而子進程的進程識別碼也會一起返回。
waitpid()函數的語法:
#include<sys/types.h>
#include<sys/wait.h>
pid_waitpid( pid_t pid , int *status, int options );
參數說明:pid:
pid>0,回收進程ID等於pid的子進程
pid=-1,回收任何一個子進程,此時和wait()相同
options:
WNOHANG 若指定的子進程沒有結束,則waitpid()不阻塞而立即返回,此時返回值為0;
WUNTRACED 為了實現某一個操作,由pid指定的任一子進程已被暫停,且其狀態自暫停以來沒有報告過,則返回其狀態。
返回值:已經結束的子進程的進程號(>0);
2014025627 《嵌入式程序設計》第五周學習總結