fork复制进程
1.fork方法的定義
pid_t fork(void) ;
函數(shù)返回類型 pid_t 實(shí)質(zhì)是 int 類型,Linux 內(nèi)核 2.4.0 版本的定義是:
fork 函數(shù)會(huì)新生成一個(gè)進(jìn)程,調(diào)用 fork 函數(shù)的進(jìn)程為父進(jìn)程,新生成的進(jìn)程為子進(jìn)程。
在父進(jìn)程中返回子進(jìn)程的 pid,在子進(jìn)程中返回 0,失敗返回-1。
2.父子進(jìn)程并發(fā)運(yùn)行
入下為fork.c代碼:
如下圖為運(yùn)行結(jié)果:
/bin/bash的pid = 33977,main的ppid = 33977,可見(jiàn)main父進(jìn)程是/bin/bash。
我們會(huì)發(fā)現(xiàn)父子進(jìn)程會(huì)交換打印,并不是先打印完父子進(jìn)=進(jìn)程中的一個(gè),很顯然,父子進(jìn)程在并發(fā)運(yùn)行。
3.父子進(jìn)程邏輯地址與物理地址和寫時(shí)拷貝
在上圖中我們打印了n的地址,發(fā)現(xiàn)父進(jìn)程的n的地址與子進(jìn)程的n的地址是同一個(gè)值,難道父子進(jìn)程用的是同一個(gè)n?答案并非如此。代碼中我們也注意父進(jìn)程的n值我們賦值為7,子進(jìn)程中的n我們負(fù)值為4,父子進(jìn)程n值不同,顯然不是 同一個(gè)n。那為什么n的地址值會(huì)相同呢?
在計(jì)算機(jī)基礎(chǔ)中我們說(shuō)了頁(yè)表的問(wèn)題。這里n值是邏輯地址,并非我們真實(shí)的物理地址。以下內(nèi)容請(qǐng)先移步到計(jì)算機(jī)基礎(chǔ),看完再看以下內(nèi)容。
當(dāng)我們fork()一個(gè)進(jìn)程的時(shí)候,系統(tǒng)會(huì)增加一個(gè)PCB(進(jìn)程控制塊),將父進(jìn)程完全復(fù)制一份,包括頁(yè)表(頁(yè)表包含邏輯頁(yè),物理頁(yè)。這也是為什么父進(jìn)程的變量值和子進(jìn)程的變量值的邏輯地址相同的原因),構(gòu)成現(xiàn)在的子進(jìn)程。一開始父進(jìn)程的頁(yè)表和子進(jìn)程的頁(yè)表一樣,所有變量的邏輯地址和物理地址都一樣,這也意味著真正意義上的共享物理空間。當(dāng)子進(jìn)程或者父進(jìn)程單獨(dú)對(duì)變量進(jìn)行修改的時(shí)候,這時(shí)候才會(huì)進(jìn)行真實(shí)物理空間的拷貝,再修改,父子進(jìn)程對(duì)這一變量不再實(shí)行共享。這就是寫時(shí)拷貝。
總結(jié)
- 上一篇: printf函数与主函数问题
- 下一篇: fork练习、从进程角度考虑堆区内存申请