記第六章--fork)
復(fù)制進程fork通過上一章我們大概了解了以下進程今天我們來講進程中的復(fù)制進程fork()我們通過打開幫助書冊得知了有關(guān)于它的一些信息:()中是2證明是系統(tǒng)調(diào)用通過create那一行可以知道fork的作用就是創(chuàng)建一個子進程那么當前這個進程就是父進程。需要兩個頭文件返回值類型:pid_t 就是進程ID的類型。下面的描述也為我們講到怎樣創(chuàng)建一個新進程就是復(fù)制調(diào)用它的進程這個是核心重點。調(diào)用fork的這個進程我們將其稱為父進程復(fù)制出來的新進程叫子進程。父子進程擁有互相獨立的內(nèi)存空間。其中需要注意的點為:子進程是從fork()開始進行不是從主函數(shù)開始執(zhí)行。從此以后兩個進程一起向上執(zhí)行我們稱此為并發(fā)運行(交替跑)。示例1下面我們通過例子來更好地了解fork:這里我們先來解析一下這個代碼:char *s:s是指針變量用來存儲字符串的地址現(xiàn)在是空的沒有指向任何字符串pid_t pidfork();pid_t是類型就像int、char那樣專門來存進程編號的數(shù)字類型pid是變量名字就像int a中的apid_t pidfork(); 就像pid這個盒子來裝fork()返回來的值如果返回值是-1那就是創(chuàng)建失敗沒有新的進程如果返回值是0就代表復(fù)制出來的是子進程如果是其他的大于0那就是父進程sleep(1):當前進程進入阻塞休眠1秒讓出cpuexit(0):進程正常退出子進程循環(huán)跑完之間exit退出子進程循環(huán)3次父進程循環(huán)7次打印順序不一定并發(fā)交替跑當然我們也可以獲得它們分別的進程ID號這是不同的通過幫助手冊我們也可以看到getpid得到自己的getppid得到父的可看出父子進程間的關(guān)系然后我們修改了一下main.c的代碼來看一下父進程與子進程在物理內(nèi)存上是不是同一塊空間我們得出了虛擬地址(邏輯地址)相同但物理地址是不同的物理地址是真實存在的它們的內(nèi)存空間是具有獨立性的就好比父子各有一棟樓兩棟樓都有0X開頭的這個編號命名的房間但這是兩個不同的房間。因為是把父進程整體復(fù)制了一塊。注:如果我們將上述子進程父進程n互換一下呢會出現(xiàn)什么結(jié)果會得出子進程循環(huán)7次父進程循環(huán)3次但是為什么看起來感覺卡頓了一下這是很正常的現(xiàn)象因為父進程循環(huán)3次已經(jīng)結(jié)束了所以就會出現(xiàn)提示符。提示符什么時候出現(xiàn)只看父進程。示例2再來一個經(jīng)典的題目:這個程序能輸出多少個A?首先我們要了解一下這個邏輯或||在c語言中它是具有短路機制的就比如左邊執(zhí)行成功那右邊就會被短路不會再執(zhí)行。這個題的答案是三個A主播思路:假設(shè)左邊f(xié)ork為真父進程是大于0的就當作p0那此時右邊被短路不進行左邊p0產(chǎn)生p1子進程目前只有一個A因為子進程0所以左邊短路此時的子進程左邊走不通開始充當父進程的角色進行右邊f(xié)ork會再有一個A然后會產(chǎn)生p1的子進程p2但p2現(xiàn)在身份是子進程所以它為0打印完它的A后不進行exit一共三個A。示例3現(xiàn)將示例2改為這樣:那現(xiàn)在是幾個A呢我們在做的時候肯定也要了解一下的機制:它的短路機制則為如果左邊是假右邊直接就不會進行如果左邊為真才會去跑右邊。主播思路:第一個fork為真就必須執(zhí)行右邊f(xié)ork相當于p0本來就要進入它進去左邊也進去右邊這時先打印一個A通過左右兩邊的fork分別復(fù)制出p1與p2子孩子p1子進程0為假就不執(zhí)行右邊打印A而右邊0為假也結(jié)束了打印一個A一共三個A。示例4fork與循環(huán)結(jié)合的進程題:猜猜看這會生成幾個A?主播思路:i0時進入循環(huán)通過fork會產(chǎn)生p0與p1此時printf了兩個Ai1時p0進去通過fork出現(xiàn)了p2此時還是兩個Ap1也是一樣的進去會出現(xiàn)p3此時還是兩個A所以你知道答案了嗎緩沖區(qū)對fork輸出結(jié)果的影響示例5看一下這個有幾個A?答案是兩個A:核心:printf行緩沖機制printf(A);這里面我們會發(fā)現(xiàn)是沒有攜帶\n的那么字符A是不會立刻打印到屏幕A僅僅留在進程的輸出緩沖區(qū)中屏幕中看不到任何東西緊接著我們就要進行fork()創(chuàng)建子進程就會有p0p1父進程緩沖區(qū)存放著A復(fù)制到子進程p1也會得到A然后兩個進程執(zhí)行exit(0)程序退出程序退出的時候操作系統(tǒng)會把緩沖區(qū)殘留的內(nèi)容刷新到屏幕所以就有了我們看到的AA。那如果給它加了/n呢\n會觸發(fā)緩沖區(qū)立即刷新A會打印到屏幕上本來是在父進程緩沖區(qū)打印出A但因為會立即刷新所以fork之后的子進程是不存在A的被清空了所以只有一個A。