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

            Linux進程創(chuàng)建,子進程對 父進程資源“寫時拷貝”的證明     傳統(tǒng)的fork()系統(tǒng)調(diào)用直接把所有的資源復(fù)制給新創(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)核此 時并不復(fù)制整個進程的地址空間,而是讓父子進程共享同一個地址空間。只用在需要寫入的時候才會復(fù)制地址空間,從而使各個進行擁有各自的地址空間。也就是 說,資源的復(fù)制是在需要寫入的時候才會進行,在此之前,只有以只讀方式共享。這種技術(shù)使地址空間上的頁的拷貝被推遲到實際發(fā)生寫入的時候。在頁根本不會被 寫入的情況下---例如,fork()后立即執(zhí)行exec(),地址空間就無需被復(fù)制了。fork()的實際開銷就是復(fù)制父進程的頁表以及給子進程創(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都會互相看到。 
            91久久精品国产91性色也| 国产精品9999久久久久| 品成人欧美大片久久国产欧美 | 国产香蕉97碰碰久久人人| 91精品国产91久久| 久久天天婷婷五月俺也去| 91久久婷婷国产综合精品青草 | 久久精品国产亚洲AV忘忧草18| 国内精品久久久久影院优| 久久精品成人| 国产精品久久久久久吹潮| 蜜臀久久99精品久久久久久| 7777久久亚洲中文字幕| 超级97碰碰碰碰久久久久最新| 久久九九有精品国产23百花影院| 亚洲精品成人网久久久久久| 99久久免费国产特黄| 日本欧美久久久久免费播放网| 久久久久久久综合综合狠狠| 国产精品久久久天天影视| 久久久久久国产精品美女| 国产精品成人久久久久三级午夜电影| 久久99精品国产自在现线小黄鸭| 久久精品久久久久观看99水蜜桃 | 久久免费看黄a级毛片| 久久国产综合精品五月天| 色综合久久中文色婷婷| 亚洲AV日韩精品久久久久久| 亚洲精品乱码久久久久久按摩| 久久久亚洲精品蜜桃臀 | 久久人人青草97香蕉| 日本免费久久久久久久网站| 精品精品国产自在久久高清| 久久棈精品久久久久久噜噜| 久久香综合精品久久伊人| 亚洲精品无码久久久久sm| 久久精品中文騷妇女内射| 欧洲成人午夜精品无码区久久| 久久国产高潮流白浆免费观看| 国内精品久久久久伊人av| 久久国产精品77777|