Linux多進程編程之 fork()&vfork()

關於進程,詳見大學必修課《操作系統》

頭文件 : #include<unistd.h>

函數: pid_t fork(void); // pid_t 是 int 類型,用來表示子進程的 pid 是一個大於0 的整數

pid_t pid=fork();//在父進程調用fork()函數

//若成功調用,一次返回兩個值,對於父進程而言,返回的是子進程的pid >0,對於子進程而言,返回的是0

//可以根據 pid 來判斷當前在哪個進程

//若 pid == -1 則表示fork()函數失敗未能創建新的進程

//若 pid == 0 表示當前進程爲子進程

//若 pid > 0 表示當前進程爲父進程

內核根據父進程複製出一個子進程,父進程和子進程的PCB信息相同,用戶態代碼和數據也相同。

即子進程將會複製fork()函數以下的所有指令,指令與數據完全獨立於父進程,與父進程只有 pid不同

getpid()函數 獲取當前進程的 pid

getppid()函數 獲取當前進程的父進程的 pid

子進程可以使用getppid()獲取父進程的 pid,父進程無法得知子進程的 pid

子進程與父進程的執行順序隨機,不知那一個優先運行和結束

sleep(int x) 函數 使當前進程掛起x秒,即x秒後繼續執行,可以控制子進程和父進程的結束順序

fork()程序示例

creatChild.c

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
 
int main()
{
	int num = 3;
	pid_t pid =  fork(); 
	printf("hello\n");//會被兩個進程執行
	if(pid==-1){
		perror("fork error");//輸出錯誤
		exit(0);
	}
	else if (pid>0){
		sleep(2);//讓子進程先執行,原因後續會講
		num++;
		printf("I am parent! num is %d\n",num);
		printf("My pid is %d\n",getpid());
	}
	else {
		num--;
		printf("I am child! num is %d\n",num);
		printf("My parent's pid is %d\n",getppid());
		printf("My pid is %d\n",getpid());
	}   
    
    return 0;
}

  

  根據運行結果我們可以看出來,兩個進程使用的是各自的num

pid_t vfork(void); //與fork作用相同,但是:

1、vfork創建的子進程和父進程之間是共享地址空間的,即數據不獨立,是共享的

2、vfork()創建的子進程必須調用 exit()或者exec()類函數才能停止,否則子進程不會結束,會發生段錯誤

3、子進程一定會優先於父進程之前執行,即使父進程被sleep掛起,子進程仍然優先執行

vfork()程序示例

vcreatChild.c

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
 
int main()
{
	int num = 3;
	pid_t pid = vfork(); 
	printf("hello\n");//會被兩個進程執行
	if(pid==-1){
		perror("fork error");//輸出錯誤
		exit(0);
	}
	else if (pid>0){
		num++;
		printf("I am parent! num is %d\n",num);
		printf("My pid is %d\n",getpid());
	}
	else {
		sleep(3);//即使是讓子進程掛起,仍然是子進程先執行 
		num--;
		printf("I am child! num is %d\n",num);
		printf("My parent's pid is %d\n",getppid());
		printf("My pid is %d\n",getpid());
		exit(0);//vfork()專屬,可以不加試試
	}   
    
    return 0;
}

  

  根據運行結果我們可以看出來,兩個進程使用的是共享的num

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