fork常用的使用場景在網絡服務進程中最常見,父進程等待客戶端的服務請求,當請求到達時,父進程調用fork使子進程處理此請求,父進程繼續等待下一個服務請求,通過fork創建的進程被稱爲子進程,該父子進程有如下特點:
1. 子進程獲得父進程數據空間,堆棧的副本,父子進程並不共享這些存儲空間,因爲使用了“寫時複製”技術,所以當在寫時纔會製作相應的副本,其它只讀默認是同一份副本
2. 共享正文段
3. 共享在fork父進程打開過的fd
使用時需要注意的點是
父進程在子進程還沒退出時就已經先退出,子進程退出了但父進程並沒有主動區獲取終止進程的有關信息,這時候子進程將會成爲殭屍進程(對於一個已經終止,但是其父進程尚未對其進行善後處理(獲取終止子進程的有關信息,釋放它仍佔用的資源)的進程稱爲殭屍進程)
下面代碼演示了簡單創建一個子進程的過程
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int globvar = 20; /*external variable in initialized data*/
void main(void)
{
int var; /*automatic variable on the stack*/
pid_t pid;
var = 88;
if (0 > (pid = fork()))
{
printf("fork error\n");
return;
}
else if (0 == pid)
{
printf("I am child process pid = %ld\n", (long)getpid());
globvar++;
var++;
}
else
{
printf("I am parent process pid = %ld\n", (long)getpid());
sleep(2);
}
printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar, var);
return;
}
編譯及運行結果如下
mcchen@mcchen-virtual-machine:/home/samba/share/mywork/test/fork$ gcc -o fork fork.c
mcchen@mcchen-virtual-machine:/home/samba/share/mywork/test/fork$ ./fork
I am parent process pid = 3645
I am child process pid = 3646
pid = 3646, glob = 21, var = 89
pid = 3645, glob = 20, var = 88
從上面運行的結果看:父進程和子進程共享代碼段,但是對數據段,棧是獨立的,不共享這些存儲空間
下一節會講下殭屍進程的產生和規避