进程创建函数fork()和vfork()
Linux下使用fork()創建一個新的進程,該函數不需要參數,返回值是一個進程id。對于不同的對象,分別是:新建的子進程id(返回給父進程),0(返回給創建的子進程)或者-1(子進程創建失敗,返回給父進程)。創建的新進程在得到一個新的進程id之后,將拷貝父進程空間中內容至子進程,包括父進程的數據段和堆棧段,并且子進程和父進程共享代碼段。vfork()和fork()則不一樣,父子進程共享地址空間,包括代碼段、數據段和堆棧段。子進程對于共享數據的修稿會影響到父進程,而且子進程一定比父進程先運行完,父進程調用vfork()函數后等待子進程運行完成再接著運行。
接下來,使用fork()創建一個子進程,并且在子進程中顯示父進程的進程號和子進程的進程id,在父進程中顯示出父進程的進程id和子進程的進程id。
#include<iostream>
#include<stdlib.h>
#include<unistd.h>
using namespace std;int main(){pid_t pid;pid = fork();if(pid < 0){cout << "Create fail!" << endl;exit(0);}else if(pid == 0){cout << "This is the child process! PID is: " << getpid() << endl;cout << "The parent process id is: " << getppid() << endl;}else{cout << "This is the parent process! PID is: " << getpid() << endl;cout << "The child process id is: " << pid << endl;}return 0;
}
編譯并運行:
發現在子進程中,由函數getppid()返回的進程號與對應的父進程的進程號并不一致。在父進程中,能夠正確返回子進程的進程id。利用ps命令查看子進程返回的父進程id對應的進程:upstart,后來在博客https://blog.csdn.net/Leafage_M/article/ details/70273624中看到一個很清楚詳細的解釋。shell中先打印出父進程的進程信息,然后再打印出子進程的進程信息,那么就相當于父進程完成之后,被殺死了,然后再執行的是子進程的信息,而此時子進程就成了孤兒進程,它被upstart這個進程收養了,此時調用getppid()返回的當然就是upstart的pid了。對于這種問題的解決方法之一就是在父進程的執行語句中加入延時掛起sleep()操作,讓父進程不至于太快銷毀。
之前說到fork()和vfork()的區別,編寫兩個實例進行驗證:
#include<iostream>
#include<stdlib.h>
#include<unistd.h>
using namespace std;int global; //全局變量(數據段中)
int main(){pid_t pid;int stack = 1; //局部變量(棧中)int* heap; //局部變量(堆中)heap = (int* )malloc(sizeof(int));*heap = 2;pid = fork();if(pid < 0){cout << "Fail to fork!" << endl;exit(1);}else if(pid == 0){global ++;stack ++;(*heap)++;cout << "This is the child process! PID is: " << getpid() << endl;cout << "The parent process id is: " << getppid() << endl;cout << "The child data: " << global << " " << stack << " " << *heap << endl;exit(0);}else{ sleep(3); cout << "This is the parent process! PID is: " << getpid() << endl;cout << "The child process id is: " << pid << endl;cout << "The parent data: " << global << " " << stack << " " << *heap << endl;exit(0);}return 0;
}
之后再將上面程序中fork()函數改為vfork(),并將延時語句注釋掉。編譯和運行結果對比:
?
可以看出,fork()創建的子進程中三個變量都發生變化時,父進程雖然在子進程之后才訪問數據,但是子進程中對變量的修改并不影響父進程的進程環境。但是vfork()則不一樣。再看進程id,在加入sleep()函數之后,fork()函數創建的子進程也能夠正常返回父進程的id了。而在vfork()函數創建的子進程中,父子進程的返回的父進程、子進程id皆一致。
fork()函數在兩種情況下容易出錯:系統中已經有很多進程,調用fork()函數的用戶進程過多。
?
總結
以上是生活随笔為你收集整理的进程创建函数fork()和vfork()的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 上海欢乐谷马戏表演时间
- 下一篇: 西方哲学十五讲的作者是谁啊?