進程控制fork vfork,父子進程,vfork保證子進程先運行


主要函數:

fork 用於創建一個新進程

exit 用於終止進程

exec 用於執行一個程序

wait 將父進程掛起,等待子進程結束

getpid 獲取當前進程的進程ID

nice 改變進程的優先級

---------------------------------

孤兒進程:

如果一個子進程的父進程先於子進程結束,子進程就成為一個孤兒進程,他由init進程收養,成為init進程的子進程。

#include <stdio.h> #include <stdlib.h> #include <unistd.h>


int main() { pid_t pid; pid = fork(); switch( pid ) { case 0: { while(1) { printf("child pid:%d, parent pid:%d\n", getpid(), getppid()); sleep(1); } } case -1: { printf("create child process error\n"); exit(-1); } default: { sleep(3); printf("I am parent,pid:%d\n", getpid()); exit(0); } } return 0; }

 

child pid:9670, parent pid:9669
child pid:9670, parent pid:9669
child pid:9670, parent pid:9669
I am parent,pid:9669
root@wilson-software:~/Project/xa# child pid:9670, parent pid:1
child pid:9670, parent pid:1
child pid:9670, parent pid:1
child pid:9670, parent pid:1
child pid:9670, parent pid:1
child pid:9670, parent pid:1

從輸出結果來看,父進程停止后,子進程變成了孤兒進程,此時子進程的父進程ID 是 1,

(init進程的進程ID值始終是1)由init進程收養。

------------------------------------------------------------------------------

vfork函數創建一個子進程時,操作系統並不將父進程的地址空間完全復制到子進程,用vfork函數創建的子進程共享父進程的地址空間,

也就是說子進程完全運行在父進程的地址空間上。子進程對該地址空間中任何數據的修改同樣為父進程所見。

使用fork創建一個子進程時,哪個進程先執行取決於系統的調度。

而vfork創建一個子進程時,vfork保證子進程先運行,子進程調用exec或者exit之前父進程處於阻塞等待狀態。

如果在調用exec或者exit之前子進程要依賴父進程的某個行為,就會導致死鎖。

如果創建子進程的目的只是為了調用exec執行某個程序,那么fork過程中子進程對父進程地址空間的復制將會是一個多余的過程。

vfork不會拷貝父進程的地址空間,這大大減小了系統開銷。

使用vfork時要謹慎,最好不要允許子進程修改與父進程共享的全局變量和局部變量

 -------------------------------------------------------------------------------------------------------------------------------------------------

父子進程結束的先后順序不同會產生不同的結果:

父進程先退出,子進程后退出,則系統會讓init進程接管子進程。

當子進程先退出,而父進程又沒有調用wait函數等待子進程結束,子進程進入僵死狀態,並且會一直保持下去除非系統重啟。子進程處於僵死狀態時,內核只保存該進程的

一些必要信息以備父進程所需。此時子進程始終占用着資源,同時也減少了系統可以創建的最大進程數。如果子進程先於父進程結束,並且父進程調用了wait或waitpid函數,

則父進程會等待子進程。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM