Linux:兩道題檢測對fork的瞭解

Linux下,當需要創建進程時,我們最常使用的就是fork()函數,但你真的瞭解它嗎?

簡略複習

我們先來複習一下fork的運行規則,詳細請參見Linux:認識進程:
功能:以父進程爲模板,創建子進程
1.會把父進程的PCB拷貝一份,部分會修改,成爲子進程的PCB
2.會把父進程的虛擬地址空間拷貝一份,作爲子進程的地址空間。

  • 寫時拷貝,父子進程公用一份代碼,各有一份數據(極端情況下代碼段也會發生拷貝)
  • 由於大部分的內存空間可能被拷貝,創建進程的開銷仍然比較高(和線程比)

3.fork 返回在父子進程中分別返回;

  • 成功:父進程中返回子進程的pid ;子進程返回0;父子進程在fork後面繼續往下執行。
  • 失敗:返回-1:原因主要是內存不夠或進程太多達到上限;

4.父子進程執行順序沒有先後關係,全靠調度器實現.

牛刀小試

在簡略地複習過後,我們就來檢測一番吧:
求程序運行結果

#include<stdio.h>
#include<usistd.h>

int main(){
	for(int i = 0;i<2;i++){
		fork();
		printf("=");
	}
	return 0;
}
結果是"========"是你所期望的嗎
  • 乍一看,主程序申請了兩個子程序,但你需要注意的是,子程序在運行時,也會運行fork();,我們來畫圖表達這一過程:
    在這裏插入圖片描述
    我們看到,當i=0時,創建一個子進程,並分別向各自緩衝區寫入一個=,當i=1時,這兩個進程又分別創建子進程,這些新的子進程將父進程緩衝區裏的=也都各自拷貝了過來,然後這四個進程都執行printf("=");至此每個進程的緩衝區都有兩個=,然後都return 0 結束函數並刷新緩衝區,打印到屏幕上的=一共有8個;
#include<stdio.h>
#include<usistd.h>

int main(){
	for(int i = 0;i<2;i++){
		fork();
		printf("=");
		fflush(stdout);
	}
	return 0;
}
結果是"======",我們來看看具體過程

在這裏插入圖片描述
這裏由於每次打印=後立即刷新緩衝區打印到屏幕上,這使得i=1時兩個進程fork子進程時並沒有拷貝=過去,然後四個進程各自輸出一個=到屏幕上,加上之前兩個共打印了6個;
這兩道題更加印證了前面所回顧的父子進程公用一份代碼,各有一份數據(極端情況下代碼段也會發生拷貝)

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