1. 進程號:linux
每一個進程在被初始化的時候,系統都會爲其分配一個惟一標識的進程id,稱爲進程號;shell
進程號的類型爲pid_t,經過getpid()和getppid()能夠獲取當前進程號和當前進程的父進程的進程號;數據結構
2. 進程複製:函數
fork函數,是以父進程爲藍本複製一個新的子進程,包括複製代碼段,數據段,堆棧段等,除了代碼段,子進程會有本身的物理內存空間,其中的內容是和父進程的數據段,堆棧段是同樣的,固然進程號是不同;spa
在linux下,fork函數是用寫複製實現的。所謂寫複製,只複製父進程的虛擬地址空間(數據結構),子進程並不會產生本身的物理內存空間,直到父進程或者子進程中有對某個段的寫行爲的時候,再爲子進程建立獨立的物理內存控制。寫複製的目的是爲了提供建立進程的效率;code
fork函數在父進程中調用一次,返回兩次。根據返回值的不一樣判斷是在父進程仍是在子進程中執行。父進程返回的是子進程的進程號,子進程返回的是0,若是失敗返回-1;blog
3. system函數:進程
建立新的進程調用shell命令,並阻塞當前進程直到shell命令執行完成;內存
不能執行返回127,成功返回進程狀態值,失敗返回-1;資源
int ret = system("ping www.baidu.com");
4. exec函數族:
exec函數會建立新的進程,並替換當前進程的資源,所以新的進程號依然和原來的進程號相同;
exec函數在執行之後不會返回,由於新的進程資源已經佔據了當前進程的資源,包括代碼段,數據段和堆棧段等,只有進程調用失敗才返回-1;
exec函數一般會在fork以後,在新的子進程中被調用,這樣的話,新的進程會佔用子進程的資源進行運行;
linux系統採用寫時複製,在fork以後若是當即調用exec函數,不會當即複製父進程的資源,而是使用exec的參數來覆蓋原有進程。除非發生了原來的內存內容發生改變時,才建立新的物理內存空間;
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> int main(int argc, char **arg) { pid_t pid = getpid(); pid_t ppid = getppid(); printf("linux net: %d %d \n", pid, ppid); pid_t cpid = fork(); int count = 1; if (cpid > 0) { printf("parent progress: %d %d %d. %d \n", cpid, getpid(), getppid(), count); count = 111; } else if (cpid == 0) { printf("child progress: %d %d %d. %d \n", cpid, getpid(), getppid(), count); count = 222; int ret = execvp("./net-exe-test", 0); printf("exec ret %d \n", ret); } else { printf("create progress failed. \n"); } printf("---------------------1 pid %d count %d \n", getpid(), count); getchar(); return 0; }