• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Prayer

            在一般中尋求卓越
            posts - 1256, comments - 190, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            fork的精辟剖析

            Posted on 2009-04-15 23:01 Prayer 閱讀(271) 評論(0)  編輯 收藏 引用 所屬分類: LINUX/UNIX/AIX
            論壇上高手對fork的精辟剖析。
            程序如下:
            #include ; 
            #include ; 
            main () 

               pid_t pid; 
                    pid=fork(); 
                    if (pid                 printf("error in fork!"); 
                    else if (pid == 0) 
                            printf("i am the child process, my process id is %dn",getpid()); 
                    else 
                            printf("i am the parent process, my process id is %dn",getpid()); 

            結果是 
            [root@localhost c]# ./a.out 
            i am the child process, my process id is 4286 
            i am the parent process, my process id is 4285
            高手一:
            要搞清楚fork的執行過程,就必須先講清楚操作系統中的“進程(process)”概念。一個進程,主要包含三個元素: 
            o. 一個可以執行的程序; 
            o. 和該進程相關聯的全部數據(包括變量,內存空間,緩沖區等等); 
            o. 程序的執行上下文(execution context)。 
            不妨簡單理解為,一個進程表示的,就是一個可執行程序的一次執行過程中的一個狀態。操作系統對進程的管理,典型的情況,是通過進程表完成的。進程表中的每一個表項,記錄的是當前操作系統中一個進程的情況。對于單 CPU的情況而言,每一特定時刻只有一個進程占用 CPU,但是系統中可能同時存在多個活動的(等待執行或繼續執行的)進程。一個稱為“程序計數器(program counter,  pc)”的寄存器,指出當前占用 CPU的進程要執行的下一條指令的位置。當分給某個進程的 CPU時間已經用完,操作系統將該進程相關的寄存器的值,保存到該進程在進程表中對應的表項里面;把將要接替這個進程占用 CPU的那個進程的上下文,從進程表中讀出,并更新相應的寄存器(這個過程稱為“上下文交換(process context switch)”,實際的上下文交換需要涉及到更多的數據,那和fork無關,不再多說,主要要記住程序寄存器 pc指出程序當前已經執行到哪里,是進程上下文的重要內容,換出 CPU的進程要保存這個寄存器的值,換入CPU的進程,也要根據進程表中保存的本進程執行上下文信息,更新這個寄存器)。 
            好了,有這些概念打底,可以說fork了。當你的程序執行到下面的語句: 
            pid=fork();  
            操作系統創建一個新的進程(子進程),并且在進程表中相應為它建立一個新的表項。新進程和原有進程的可執行程序是同一個程序;上下文和數據,絕大部分就是原進程(父進程)的拷貝,但它們是兩個相互獨立的進程!此時程序寄存器pc,在父、子進程的上下文中都聲稱,這個進程目前執行到fork調用即將返回(此時子進程不占有CPU,子進程的pc不是真正保存在寄存器中,而是作為進程上下文保存在進程表中的對應表項內)。問題是怎么返回,在父子進程中就分道揚鑣。 
            父進程繼續執行,操作系統對fork的實現,使這個調用在父進程中返回剛剛創建的子進程的pid(一個正整數),所以下面的if語句中pid子進程在之后的某個時候得到調度,它的上下文被換入,占據 CPU,操作系統對fork的實現,使得子進程中fork調用返回0。所以在這個進程(注意這不是父進程了哦,雖然是同一個程序,但是這是同一個程序的另外一次執行,在操作系統中這次執行是由另外一個進程表示的,從執行的角度說和父進程相互獨立)中pid=0。這個進程繼續執行的過程中,if語句中pid為什么看上去程序中互斥的兩個分支都被執行了?在一個程序的一次執行中,這當然是不可能的;但是你看到的兩行輸出是來自兩個進程,這兩個進程來自同一個程序的兩次執行。
            fork之后,操作系統會復制一個與父進程完全相同的子進程,雖說是父子關系,但是在操作系統看來,他們更像兄弟關系,這2個進程共享代碼空間,但是數據空間是互相獨立的,子進程數據空間中的內容是父進程的完整拷貝,指令指針也完全相同,但只有一點不同,如果fork成功,子進程中fork的返回值是0,父進程中fork的返回值是子進程的進程號,如果fork不成功,父進程會返回錯誤。 
            可以這樣想象,2個進程一直同時運行,而且步調一致,在fork之后,他們分別作不同的工作,也就是分岔了。這也是fork為什么叫fork的原因。 
            在程序段里用了fork()之后程序出了分岔,派生出了兩個進程。具體哪個先運行就看該系統的調度算法了。 
            如果需要父子進程協同,可以通過原語的辦法解決。
            高手二:
            進程的創建: 
            創建一個進程的系統調用很簡單.我們只要調用fork函數就可以了. 
            #include  
            pid_t fork();
            當一個進程調用了fork以后,系統會創建一個子進程.這個子進程和父進程不同的地方只有他的進程ID和父進程ID,其他的都是一樣.就象父進程克隆(clone)自己一樣.當然創建兩個一模一樣的進程是沒有意義的.為了區分父進程和子進程,我們必須跟蹤fork的返回值. 當fork掉用失敗的時候(內存不足或者是用戶的最大進程數已到)fork返回-1,否則fork的返回值有重要的作用.對于父進程fork返回子進程的 ID,而對于fork子進程返回0.我們就是根據這個返回值來區分父子進程的. 父進程為什么要創建子進程呢?前面我們已經說過了Linux是一個多用戶操作系統,在同一時間會有許多的用戶在爭奪系統的資源.有時進程為了早一點完成任務就創建子進程來爭奪資源. 一旦子進程被創建,父子進程一起從fork處繼續執行,相互競爭系統的資源.有時候我們希望子進程繼續執行,而父進程阻塞,直到子進程完成任務.這個時候我們可以調用wait或者waitpid系統調用. 
               總結一下有三:
            1,派生子進程的進程,即父進程,其pid不變; 
            2,對子進程來說,fork返回給它0,但它的pid絕對不會是0;之所以fork返回0給它,是因為它隨時可以調用getpid()來獲取自己的pid; 
            3,fork之后父子進程除非采用了同步手段,否則不能確定誰先運行,也不能確定誰先結束。認為子進程結束后父進程才從fork返回的,這是不對的,fork不是這樣的,vfork才這樣。 
            人人狠狠综合久久亚洲婷婷| 久久人人爽人人爽人人AV东京热 | 免费国产99久久久香蕉| 久久精品嫩草影院| 欧美粉嫩小泬久久久久久久| 久久精品国产99久久久古代| 国产精品禁18久久久夂久| 9191精品国产免费久久| 亚洲人成无码www久久久| 久久无码人妻一区二区三区| 天天综合久久久网| 久久只有这精品99| 久久成人影院精品777| 无码国内精品久久人妻麻豆按摩 | 亚洲欧美国产精品专区久久| 欧洲成人午夜精品无码区久久 | 麻豆av久久av盛宴av| 狠狠色丁香婷综合久久| 日本加勒比久久精品| 久久91综合国产91久久精品| 久久91精品国产91久| 丰满少妇人妻久久久久久4| 偷偷做久久久久网站| 97超级碰碰碰碰久久久久| 国内精品伊人久久久久妇| 国产激情久久久久影院老熟女| 久久亚洲精品成人无码网站 | 亚洲国产日韩欧美综合久久| 国产成人久久精品区一区二区| 热久久最新网站获取| 国产精品亚洲美女久久久| 7777久久亚洲中文字幕| 99久久香蕉国产线看观香| 国产成人久久精品二区三区| 中文字幕久久精品无码| 久久影院亚洲一区| 国产高潮久久免费观看| 精品久久777| 久久99精品国产一区二区三区| 亚洲午夜久久久久久久久久| 青春久久|