多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > 綜合技術 > JOS fork函數 實現機制分析

JOS fork函數 實現機制分析

來源:程序員人生   發布時間:2015-05-20 11:11:33 閱讀次數:4147次

JOS fork函數 實現機制分析


簡直有點小雞凍哇... 介個地方之前困惑了好1陣...現在叨叨關于fork那些事兒


文章會側重分析fork的兩種實現策略:


              1. 不使用COW 策略實現dumbfork (很暴力的拷貝)

              2. 使用COW技術的fork(寫時復制, parent process , child process任意1個進程對共同映照的空間有改動,就產生拷貝動作, 改動了哪頁拷貝哪頁, 不是全部user space空間的拷貝).





大家都知道, 在Unix類系統里面, 創建1個子進程最經常使用的就是fork.

而且有個很牛逼轟轟的技術,叫做COW(copy on write) 被利用在這上面. 


首先說明1個連接器細節. 每一個linker在生成最后的可履行程序的時候,都會在bss段的末尾做個標記 -- end.

可以把這個end當作1個全局變量,是個指針,指向bss段的末尾.(bss本來就是所有段的末尾,那末這個指針指向的可履行程序的末尾..而bss段又幾近不占空間的,因而其實又是指向數據段的末尾的.)



左側的是 obj/kern/kernel.sym的部份截圖                          右側的是 obj/user/dumbfork.sym



我們關注end標記就能夠了. 每一個程序編譯完了以后都會在 bss段后面加上 end.

在用戶空間程序里面援用的就是用戶空間這個end, 而不是內核那個



這是1個很有必要的background.下面我們來分析兩種fork 策略



1. dumbfork.c  (我不貼全部的代碼,只做重要的理論分析, 全部代碼可以去github看, 這樣寫出來的東西才成心義)

這里sys_exofork僅僅只是為新進程分配了1個新的 env結構體, 用來描寫新的子進程.

 而子進程的用戶空間內存還沒有分配.  



之前我在這里恐慌了好久, 我很狐疑, 為何這里就敢給子進程的全局變量thisenv賦值呢? 后面可是會duppage把全部parent process的用戶空間數據拷貝過去的啊. 不就覆蓋了么. 這賦值操作不就白做了么? 我很當時很愁悶(年輕人啊, too young too naive啊...). 要知道這里子進程可還是沒有運行的! 所以壓根還不會產生thisenv的賦值操作, 子進程還沒有運行, 等parent運行快完了, 才會把child 設置成 runable.以后才會運行子進程, 進而進入 if (envid == 0)


再繼續看看,究竟怎樣copy parent process到child process的.

調用duppage() 把從 UTEXT開始的地址處1直拷貝到end (客官如果忘記的話,往前翻)


其實這里UTEXT ~ end只有不是很大的1段用戶空間. (建議自己去cprintf, 把這兩個地址打印出來, 然后對比 memlayout.h去看, 瞬間就明白了. 我之前在這里被坑了幾天, 各種毀3觀)


最后, 我們把用戶的可履行程序, 全局變量神馬的都拷貝了(for循環里面的duppage).但是我們還沒有拷貝棧啊. 棧的地址在 end的上面. 

因而就有了 duppage(envid, ROUNDDOWN(& addr, PGSIZE));

這里又恐慌了好久, 由于我沒有注意到他傳入的是指針addr的地址, 而不是addr指向的地址.我伙呆, 由于這里addr是個函數局部變量, 是在棧上面的. 因而利用這個地址是個棧上地址, 再ROUNDDOWN就找到棧最低地址了,直接duppage. 因而就弄定了user space stack的拷貝. 也就完成了進程的拷貝.



2. lib/fork.c


要看懂這個fork實現1定要明白user space page fault handler機制.這個是N多策略的基礎.

傳送門:http://blog.csdn.net/cinmyheart/article/details/45271455


看前面和dumbfork還是很相似的,都是調用sys_exofork來取得1個新的struct env.


不同的是后面.究竟是怎樣實現COW(copy on write)的呢? 

后面兩層for循環, 根據頁目錄也頁表對存在的頁(PTE_P), 除異常棧以外統統映照.

而后, 異常棧是兩個進程,產生write操作之前, 唯1不同享的內存區域. 后面單獨給異常棧映照內存.


還是duppage.


策略超贊. 首先不管原來的頁面是不是是可以寫的(PTE_W or PTE_COW), 都把當前進程的頁面以 

perm = PTE_U | PTE_P進行映照.  

1. 如果有可以PTE_W或PTE_COW,

那末我們都以 perm = PTE_U | PTE_P | PTE_COW進行映照 ,注意不要給PTE_W權限了.

2.如果perm里面存在PTE_COW,那末就以perm = PTE_U | PTE_P | PTE_COW重新映照本身



等duppage完事的時候, 兩個進程空間內, 相同的虛擬地址所有的權限都是1樣的(還是除開異常棧).

兩個進程中, 任意1個進程嘗試對頁面進行寫操作的時候, 都會觸發page fault, 由于沒有 PTE_W權限.

而這里user space 的page fault handler則會PTE_P | PTE_W | PTE_U的權限重新申請1頁物理內存去添加到對應進程中去. 


哎, 感覺這么清楚直觀的機制, 我之前怎樣就死糾結捏.... 折騰好久了這個fork. 今天算是有個交代了~








生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产精品一区二区三区免费 | 精品国产欧美一区二区 | 91亚洲精品福利在线播放 | 亚洲 成人 欧美 自拍 | 波多野结衣在线视频观看 | 欧美黑人性猛交 | 国产免费高清mv视频在线观看 | 狠狠操网站| 操一炮在线 | 手机在线成人精品视频网 | 免费的国语一级淫片 | 日本特黄一级大片 | 欧美色欧美 | 久一视频在线观看 | 欧美日韩乱码毛片免费观看 | 日韩欧美第一区二区三区 | 欧美色阁 | 国产日本欧美在线观看乱码 | 亚洲视频精选 | 美女上床网站 | 色综合第一页 | 成人卡通精品卡通动漫第一页 | 在线看片777av免费观看 | 在线观看视频网站 | 国产亚洲一区二区在线观看 | 欧美日韩精品一区二区 | 精品福利在线观看 | 国产精品嫩草影院免费看 | 成人69视频在线观看免费 | 国产亚洲综合视频 | 99热精品成人免费观看 | 337p日本欧美在线观看 | 欧美日韩亚洲国产精品一区二区 | 日韩欧美自拍 | 国产欧美亚洲精品a | 日本欧美做爰全免费的视频 | 小说区乱图片区 | 另类亚洲图片 | 国产成人综合手机在线播放 | 亚洲精品一区二区三区婷婷月 | 婷婷在线成人免费观看搜索 |