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

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

            #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);
                }
            }
            運行結(jié)果
            Child process 6427, data 10
            Child process 6427, data 20
            Parent process 6426, data 10 

                第1個Child process 6427, data 10是因為子進程創(chuàng)建時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);
            }

            運行結(jié)果將是
            Child process 6443, data 10
            Child process 6443, data 20
            Parent process 6442, data 20

                由于使用了CLONE_VM創(chuàng)建進程,子進程的mm實際直接指向父進程的mm,所以data是同一份。改變父子進程的data都會互相看到。 
            精品伊人久久久| 久久精品无码一区二区WWW| 久久精品国产亚洲av麻豆小说| 亚洲国产一成人久久精品| 国产精品99久久久精品无码| 久久99国产精品尤物| 久久久99精品成人片中文字幕 | 国产精品成人久久久久三级午夜电影 | 久久综合鬼色88久久精品综合自在自线噜噜 | 狠狠色狠狠色综合久久| 久久九九亚洲精品| 人妻无码αv中文字幕久久琪琪布| 亚洲精品tv久久久久久久久 | 国产精品一区二区久久国产| 日批日出水久久亚洲精品tv| 成人国内精品久久久久影院| 中文字幕亚洲综合久久菠萝蜜| 久久精品国产精品亚洲精品| 亚洲精品国产美女久久久| 亚洲人AV永久一区二区三区久久| 国产精品9999久久久久| 2021国内久久精品| 亚洲国产高清精品线久久| 久久久久夜夜夜精品国产| 国产亚洲精久久久久久无码77777 国产亚洲精品久久久久秋霞 | 亚洲国产另类久久久精品黑人| 久久99精品国产麻豆婷婷| 成人国内精品久久久久一区| 久久久久久久久波多野高潮| 欧美午夜A∨大片久久| 狠狠色综合久久久久尤物| 青青草原综合久久| 久久久久久久尹人综合网亚洲 | 亚洲v国产v天堂a无码久久| 四虎久久影院| 国产欧美久久久精品影院| 亚洲日本久久久午夜精品| 精品久久久久久无码不卡| 丁香色欲久久久久久综合网| 五月丁香综合激情六月久久| 久久久婷婷五月亚洲97号色|