<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Linux 寫(xiě)時(shí)復(fù)制機(jī)制原理

          共 1358字,需瀏覽 3分鐘

           ·

          2021-05-09 10:17

          在 Linux 系統(tǒng)中,調(diào)用 fork 系統(tǒng)調(diào)用創(chuàng)建子進(jìn)程時(shí),并不會(huì)把父進(jìn)程所有占用的內(nèi)存頁(yè)復(fù)制一份,而是與父進(jìn)程共用相同的內(nèi)存頁(yè),而當(dāng)子進(jìn)程或者父進(jìn)程對(duì)內(nèi)存頁(yè)進(jìn)行修改時(shí)才會(huì)進(jìn)行復(fù)制 —— 這就是著名的 寫(xiě)時(shí)復(fù)制 機(jī)制。

          下面我們將分析 Linux 寫(xiě)時(shí)復(fù)制(Copy On Write) 機(jī)制的原理。

          虛擬內(nèi)存與物理內(nèi)存

          進(jìn)程的內(nèi)存可分為 虛擬內(nèi)存物理內(nèi)存

          • 物理內(nèi)存:就是電腦安裝的內(nèi)存條,如果電腦安裝了2GB的內(nèi)存條,那么系統(tǒng)就用于 0 ~ 2GB 的物理內(nèi)存空間。

          • 虛擬內(nèi)存:虛擬內(nèi)存是使用軟件虛擬的,在 32 位操作系統(tǒng)中,每個(gè)進(jìn)程都獨(dú)占 4GB 的虛擬內(nèi)存空間。

          應(yīng)用程序使用的是 虛擬內(nèi)存,比如 C 語(yǔ)言取地址操作符號(hào) & 所得到的地址就是 虛擬內(nèi)存地址。而 虛擬內(nèi)存地址 需要映射到 物理內(nèi)存地址 才能使用,如果使用沒(méi)有映射的 虛擬內(nèi)存地址,將會(huì)導(dǎo)致 缺頁(yè)異常

          虛擬內(nèi)存地址 映射到 物理內(nèi)存地址 如下圖所示:



          如上圖所示,進(jìn)程A與進(jìn)程B的相同 虛擬內(nèi)存地址 映射到不同的 物理內(nèi)存地址,這就是不同進(jìn)程的相同虛擬內(nèi)存地址互不影響的原因。

          寫(xiě)時(shí)復(fù)制原理

          前面介紹了 虛擬內(nèi)存物理內(nèi)存 的概念,接下來(lái)將會(huì)介紹 Linux 寫(xiě)時(shí)復(fù)制 的原理。

          前面說(shuō)過(guò),虛擬內(nèi)存 需要與 物理內(nèi)存 進(jìn)行映射才能使用,如果不同進(jìn)程的 虛擬內(nèi)存地址 映射到相同的 物理內(nèi)存地址,那么就實(shí)現(xiàn)了共享內(nèi)存的機(jī)制。如下圖所示:



          由于進(jìn)程A的 虛擬內(nèi)存M 與進(jìn)程B的 虛擬內(nèi)存M' 映射到相同的 物理內(nèi)存G,所以當(dāng)修改進(jìn)程A 虛擬內(nèi)存M 的數(shù)據(jù)時(shí),進(jìn)程B 虛擬內(nèi)存M' 的數(shù)據(jù)也會(huì)跟著改變。

          Linux 為了加速創(chuàng)建子進(jìn)程過(guò)程與節(jié)省內(nèi)存使用的原因,實(shí)現(xiàn)了 寫(xiě)時(shí)復(fù)制 的機(jī)制。

          寫(xiě)時(shí)復(fù)制 的原理大概如下:

          • 創(chuàng)建子進(jìn)程時(shí),將父進(jìn)程的 虛擬內(nèi)存物理內(nèi)存 映射關(guān)系復(fù)制到子進(jìn)程中,并將內(nèi)存設(shè)置為只讀(為什么要設(shè)置為只讀?)。

          • 當(dāng)子進(jìn)程或者父進(jìn)程對(duì)內(nèi)存數(shù)據(jù)進(jìn)行修改時(shí),便會(huì)觸發(fā) 寫(xiě)時(shí)復(fù)制 機(jī)制:將原來(lái)的內(nèi)存頁(yè)復(fù)制一份新的,并重新設(shè)置其內(nèi)存映射關(guān)系,將父子進(jìn)程的內(nèi)存讀寫(xiě)權(quán)限設(shè)置為可讀寫(xiě)。

          寫(xiě)時(shí)復(fù)制 過(guò)程如下圖所示:



          從上圖可知,當(dāng)創(chuàng)建子進(jìn)程時(shí),父子進(jìn)程指向相同的 物理內(nèi)存,而不是將父進(jìn)程所占用的 物理內(nèi)存 復(fù)制一份。這樣做的好處有兩個(gè):

          • 加速創(chuàng)建子進(jìn)程的速度。

          • 減少進(jìn)程對(duì)物理內(nèi)存的使用。

          但這個(gè)時(shí)候只能對(duì)內(nèi)存進(jìn)行讀操作,如果父進(jìn)程或子進(jìn)程對(duì)內(nèi)存進(jìn)行寫(xiě)操作,那么將會(huì)觸發(fā) 缺頁(yè)異常,而在 缺頁(yè)異常 處理中會(huì)對(duì)物理內(nèi)存進(jìn)行復(fù)制,并且重新映射其內(nèi)存映射關(guān)系。

          復(fù)制并重新映射到新的物理內(nèi)存后,父子進(jìn)程的虛擬內(nèi)存就映射到不同的物理內(nèi)存上,這時(shí)父子進(jìn)程都可以對(duì)內(nèi)存進(jìn)行寫(xiě)操作而互不影響,所以需要把父子進(jìn)程的內(nèi)存讀寫(xiě)權(quán)限設(shè)置為可讀寫(xiě)。

          總結(jié)

          本篇文章主要介紹了 Linux 寫(xiě)時(shí)復(fù)制 的原理,寫(xiě)時(shí)復(fù)制 是 Linux 創(chuàng)建子進(jìn)程高效的關(guān)鍵所在,而且還能節(jié)省對(duì)物理內(nèi)存使用。我們將在下一篇文章中對(duì) 寫(xiě)時(shí)復(fù)制 的實(shí)現(xiàn)進(jìn)行詳細(xì)的分析。

          瀏覽 44
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本三级精品视频 | 免费特级黄色片 | 圆产精品久久久久久久久久久新郎 | 操逼黄视频 | 丁香六月欧美 |