• <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都會互相看到。 
            久久国产精品-国产精品| 女同久久| 日本久久久久久中文字幕| 久久这里只有精品视频99| 中文字幕人妻色偷偷久久| 93精91精品国产综合久久香蕉| 伊人 久久 精品| 91久久精品国产91性色也| 狠狠色噜噜色狠狠狠综合久久| 99久久国产综合精品五月天喷水| 亚洲中文久久精品无码| 久久人妻少妇嫩草AV无码蜜桃| 久久国产精品成人免费 | 久久国产热精品波多野结衣AV| 久久久久亚洲AV成人网人人网站| 久久久国产乱子伦精品作者| 亚洲精品午夜国产va久久| 热久久国产精品| 99re这里只有精品热久久| 人妻无码久久一区二区三区免费 | 色婷婷综合久久久久中文| 亚洲а∨天堂久久精品| 狠狠色伊人久久精品综合网 | 精品无码久久久久国产动漫3d| 久久精品国产清自在天天线| 热久久国产精品| 久久国产乱子伦精品免费强| 国产亚洲色婷婷久久99精品| 浪潮AV色综合久久天堂| 亚洲国产精品无码成人片久久| 久久精品免费全国观看国产| 四虎国产精品成人免费久久| 亚洲欧美成人久久综合中文网| 欧美无乱码久久久免费午夜一区二区三区中文字幕 | 麻豆精品久久精品色综合| 久久免费高清视频| 26uuu久久五月天| 久久精品中文字幕有码| 久久亚洲视频| 亚洲中文字幕无码久久2020| 久久国产精品一国产精品金尊 |