轉載:http://blog.sina.com.cn/s/blog_69708ebe0100rc3i.htmlhtml
1,通俗來說,進程是系統中正在運行的一個程序,程序一旦運行就是進程。但要把進程和程序區分開來,程序代碼儲存在內存空間,它是靜態的,它是保存在磁盤上的指令的有序集合,沒有任何執行的概念,而進程是動態的,它的生命週期有三種狀態:就緒態,執行態,等待態。一個進程執行後能夠被消亡,可是程序依然存在,只是此時這個程序不執行而已;linux
2,進程能夠當作程序執行的一個實例。進程是系統資源分配的獨立實體,每一個進程都擁有獨立的地址空間。一個進程沒法訪問另外一個進程的變量和數據結構,若是想讓一個進程訪問另外一個進程的資源,須要使用進程間通訊,好比管道,文件,套接字等。數據結構
3,一個程序運行起來可產生一個或多個進程,一個進程也能夠包含多個程序,他們不是一一對應關係;
4,進程是系統的基本調度單位,那麼怎樣區分不一樣的進程呢?每一個進程都有本身的身份證(進程標識),其中最重要的標識是進程號(PID)和它的父進程號(PPID),他們都是非零的正整數,可分別經過getpid()和getppid()獲得進程號和父進程號;函數
linux中的進程包含三個段:
數據段:存放全局變量,常數以及動態數據分配的數據空間(如malloc函數取得的空間)等;
代碼段:固然是存代碼!!!
堆棧斷:存子程序的返回地址,子程序的參數和局部變量;spa
linux中,進程的執行分用戶模式和內核模式;用戶進程可在兩種模式下運行;
建立進程:
fork();在一個進程中建立一個新進程(子進程),該子進程徹底拷貝了父進程的所有內容(複製父進程數據和堆棧空間等);
vfork()和fork()有一個區別: Linux使用copy-on-write(COW)技術,只有當其中一進程試圖修改欲複製的空間時纔會作真正的複製動做,因爲這些繼承的信息是複製而來,並不是指相同的內存空間,所以子進程對這些變量的修改和父進程並不會同步。此外,子進程不會繼承父進程的文件鎖定和未處理的信號。
exec函數族:提供了一個在進程中啓動另外一個執行程序的方法;exec函數族共有6個函數,具體用法請查看linux_c函數參考手冊,下面是幾個例子供參考:code
#include<unistd.h> #include<stdio.h> #include<stdlib.h> int main() { if(fork()==0) //若返回值爲0,是子進程 { if(execl("/bin/rm","rm","hello",NULL)<0) perror("execlp error "); } return 0; }
#include<unistd.h> #include<stdio.h> #include<stdlib.h> int main() { if(fork()==0) //子進程 { if(execlp("touch","touch","hello",NULL)<0) perror("execlp error "); } return 0; }
exit()和_exit();這兩個函數都是用來終止進程的,區別就在exit()在終止進程前要檢查文件打開的狀況,會把緩衝區的數據寫回文件,這個操做跟「緩衝IO」有關,本身去想吧!!htm
_exit()直接結束進程。
wait()和waitpid()
怎樣用本身去看書,我直接給出例子,不要怪我哦,我打字打到這裏是在太累了,哈:blog
#include<sys/types.h> #include<sys/wait.h> #include<stdio.h> #include<stdlib.h> #include<unistd.h> int main() { pid_t pc,pr; pc=fork();//產生一個子進程 if(pc<0)//出錯 perror("fork"); else if(pc==0) //返回值爲0,是子進程 { sleep(5); exit(0); } else //爲父進程 { do { pr=waitpid(pc,NULL,WNOHANG); if(pr==0) { printf("the child process has not exit\n"); sleep(1); } }while(pr==0); if(pr==pc) printf("Get child %d",pr); else printf("somer error occured"); } }