通過Linux啟動過程可以得知,所有進程都是init進程直接或者間接的fork出來的.
首先咱們來看看怎么創建子進程:
頭文件 #include <unistd.h>
int fork(void); //創建一個子進程(開辟和父進程相同空間)
返回值:-1失敗,成功返回創建的子進程的Id
int vfork(void); //創建一個子進程(共享父進程資源空間)
返回值:-1失敗,成功返回創建的子進程的Id
- int pid = fork();
- int c = 0;
- if(pid == 0){ //返回值在子進程中為0;所以當等於0時就是在子進程中運行
- c++;
- printf("children,c=%d\n",c);
- }else if(pid > 0){ //返回值在父進程中就是子進程的PID號,所以大於0就是在父進程中執行
- c++;
- printf("father,c=%d\n",c);
- }else { //小於0,子進程創建失敗
- printf("子進程創建失敗\n");
- }
結果為:children,c=1
father,c=1
因為是拷貝父進程的資源,所以變量c也被拷貝了一份到子進程,所以在父子進程中對變量c進行操作不會相互影響,而且父子進程誰先執行誰后執行由系統進程調度決定,而使用vfork()函數則會共享,而且需要注意的是vfork函數產生的子進程會被優先調度,父進程會等子進程運行結束以后才會被調用,而且子進程結束以后必須調用exit函數返回,否則進程異常退出.
- int c = 0;
- int pid = vfork();
- if(pid == 0){
- c++;
- printf("c c=%d\n",c);
- exit(0); //調用該函數返回
- }
- if(pid > 0){
- c++;
- printf("f c=%d\n",c);
- }
- if(pid < 0){
- printf("子進程創建失敗\n");
- }
運行結果為:c c=2;
f c=3;
vfork函數使得父進程等待子進程完成工作后調用可以防止子進程成為僵屍進程,而且節約內存空間,所以在滿足需求的情況下可以盡量選擇vfork函數創建子進程.
------------------------------------------------------------------------------------------------
一些其他的相關函數:
頭文件<sys/types.h>,<unsid.h>
int getpid(void);//得到進程Id
int getppid(void);//得到父進程Id
頭文件<sys/types.h><sys/wait.h>
int wait(int *status);//暫停目前進程的執行,直到有信號來激活或者子進程執行結束
int waitpid(int pid,int *status,int options);
//等待pid代表的子進程的執行結束,pid = -1,相當於wait。等待任何子進程
頭文件<unsid.h>
unsigned int sleep(unsigned int seconds)//當前進程休眠
頭文件<unsid.h>
void exit(int status);//結束進程,更新緩存區
oid _exit(int status);//結束進程,清空緩存區