進程之fork函數基本使用

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

從上面運行的結果看:父進程和子進程共享代碼段,但是對數據段,棧是獨立的,不共享這些存儲空間

下一節會講下殭屍進程的產生和規避

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章