• <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>
            posts - 200, comments - 8, trackbacks - 0, articles - 0
            今天看到寫時拷貝這個概念,當時一下沒有理解,后來查看一些網上的資料,找到了這篇文章,里面的那份個小程序能夠很好的說明進程創建寫時拷貝的概念。怕以后找不到就轉載了。嘿嘿。
            下面是那篇文章的原文:

            Linux進程創建,子進程對 父進程資源“寫時拷貝”的證明     傳統的fork()系統調用直接把所有的資源復制給新創建的進程。這種實現過于簡單并且效率低下,因為它拷貝的數據或許可以共享(This approach is significantly na?ve and inefficient in that it copies much data that might otherwise be shared.)。更糟糕的是,如果新進程打算立即執行一個新的映像,那么所有的拷貝都將前功盡棄。
                Linux的fork()使用寫時拷貝 (copy- on-write)頁實現。寫時拷貝是一種可以推遲甚至避免拷貝數據的技術。內核此 時并不復制整個進程的地址空間,而是讓父子進程共享同一個地址空間。只用在需要寫入的時候才會復制地址空間,從而使各個進行擁有各自的地址空間。也就是 說,資源的復制是在需要寫入的時候才會進行,在此之前,只有以只讀方式共享。這種技術使地址空間上的頁的拷貝被推遲到實際發生寫入的時候。在頁根本不會被 寫入的情況下---例如,fork()后立即執行exec(),地址空間就無需被復制了。fork()的實際開銷就是復制父進程的頁表以及給子進程創建一 個進程描述符。下列程序可證明寫時拷貝:

            #include <stdio.h>

            #include <sched.h>

            int data = 10;

            int child_process()
            {
                printf("Child process %d, data %dn",getpid(),data);
                data = 20;
                printf("Child process %d, data %dn",getpid(),data);
                while(1);
            }

            int main(int argc, char* argv[])
            {
                if(fork()==0) {
                  child_process();    
                }else{
                    sleep(1);
                    printf("Parent process %d, data %dn",getpid(), data);
                    while(1);
                }
            }
            運行結果
            Child process 6427, data 10
            Child process 6427, data 20
            Parent process 6426, data 10 

                第1個Child process 6427, data 10是因為子進程創建時task_struct的mm直接拷貝自parent的mm;第2個Child process 6427, data 20是因為子進程進行了“寫時拷貝”,有了自己的dataa;第3個Parent process 6426, data 10輸出10是因為子進程的data和父進程的data不是同一份。
                如果把上述程序改為:

            #include <stdio.h>
            #include <sched.h>
            #include <stdlib.h>

            int data = 10;

            int child_process()
            {
                printf("Child process %d, data %dn",getpid(),data);
                data = 20;
                printf("Child process %d, data %dn",getpid(),data);
                while(1);
            }

            int main(int argc, char* argv[])
            {
                void **child_stack;
                child_stack = (void **) malloc(16384);
                clone(child_process, child_stack, CLONE_VM|CLONE_FILES|CLONE_SIGHAND, NULL);

                sleep(1);
                printf("Parent process %d, data %dn",getpid(), data);
                while(1);
            }

            運行結果將是
            Child process 6443, data 10
            Child process 6443, data 20
            Parent process 6442, data 20

                由于使用了CLONE_VM創建進程,子進程的mm實際直接指向父進程的mm,所以data是同一份。改變父子進程的data都會互相看到。 
            91精品国产色综久久| 久久精品国产亚洲AV忘忧草18| 亚洲中文字幕无码久久综合网| 久久精品卫校国产小美女| 国产亚洲精久久久久久无码| 97久久超碰成人精品网站| 国产成人久久777777| 色综合久久久久综合99| 久久久精品人妻一区二区三区蜜桃| 久久ww精品w免费人成| 人妻中文久久久久| 国产成人精品久久二区二区| 久久强奷乱码老熟女网站| 人妻无码αv中文字幕久久| 久久精品?ⅴ无码中文字幕| 久久午夜无码鲁丝片秋霞| 精品一区二区久久| 久久精品国产男包| 亚洲v国产v天堂a无码久久| 日本三级久久网| 看久久久久久a级毛片| 欧美精品国产综合久久| 精品久久久久久无码国产| 国产∨亚洲V天堂无码久久久| 色偷偷91久久综合噜噜噜噜| 99久久国产热无码精品免费久久久久| 精品久久亚洲中文无码| 亚洲国产精品无码久久九九| 国内精品伊人久久久久影院对白| WWW婷婷AV久久久影片| 久久婷婷成人综合色综合| 久久久久久精品免费看SSS| 日韩久久无码免费毛片软件 | 久久天天婷婷五月俺也去| 久久er热视频在这里精品| 久久久久国产精品熟女影院| 国产亚洲精久久久久久无码77777| 亚洲国产综合久久天堂 | 久久精品国产亚洲av麻豆图片 | 久久国产精品无码一区二区三区 | 国产91久久精品一区二区|