linux進程的地址空間,核心棧,使用者棧,核心線程

來源:互聯網
上載者:User

地址空間:

32位linux系統上,進程的地址空間為4G,包括1G的核心地址空間,和3G的使用者地址空間。

核心棧:

進程式控制制塊task_struct中儲存了2個page大小的資訊。

為什麼每一個進程都是用各自的核心棧呢?


引用(http://hi.baidu.com/iruler/blog/item/0c3363f377ccc5c90a46e023.html)“

假設某個進程通過系統調用運行在核心態(使用這個全域核心堆棧),此時如果被搶佔,發生一次切換,另一個進程開始運行,如果這個當前進程又通過系統調用陷入核心,那麼這個進程也將使用這個全域核心堆棧,這樣的話就把以前那個進程的核心空間堆棧給破壞了。 
而如果進程使用獨立的核心棧,就避免了這種情況的發生

核心線程:

擁有自己獨立核心棧的調度單元,可以參與調度,在核心空間執行。


使用者棧:

每一個線程有一個使用者棧,由ss和esp指向。


===================================================

                         進程1                                進程2

核心代碼區      kcode (0xc0001000)        
 kcode (0xc0001000)  

核心棧區          kstack(0xc000F000)          kstack(0xc001F000)

核心棧區          kstack(0xc000D000)          kstack(0xc001D000)

...

核心資料區      kdata  (0xc0003000)          kdata  (0xc0003000)

---------------------------------------------------------------------------------------------

使用者代碼區      ucode  (0x70001000)        ucode (0x70001000) 

使用者棧區          ustack (0x7000F000)        ustack (0x7000F000) 

使用者棧區          ustack (0x7000D000)        ustack (0x7000D000) 

...

使用者資料區      udata   (0x70003000)        udata  (0x70003000) 

===================================================

合理的解釋:

核心1G空間的映射頁表(256個entries*4M)只有一份,n個進程共用(都複製了一份在自己的進程頁表內, 256個核心的entries+768個使用者空間的entries, 總共1024個entries,假定使用4M頁面,並且一開始就全都分配好)。

每個進程使用者空間的這些entries各不相同,比如說,同樣的0x70001000虛擬位址, 進程1指向實體記憶體0x2000, 而進程2指向0x1000。

每個線程對應的核心棧的虛擬位址不重疊。

thread1's kernel stack  = 0f000,

thread2's
kernel stack  = 0d000,

thread3's
kernel stack  = 1f000,

thread4's
kernel stack  = 1d000

...

思考1:

如果核心棧不是預先分配好的(分配的意思是指"在核心空間中分出一段一段不重疊空間作為各個線程的棧", e.g. kmalloc調用),那麼步入核心態的時候, 壓棧,發生缺頁異常,必須對核心棧佔用的這個頁進行換頁,而換頁曆程的調用必然涉及參數的壓棧出棧,而這個時候核心棧沒有就緒,異常發生嵌套,系統出錯!


思考2:

在核心裡面做kmalloc是可以的,添加一個entries,關聯一塊實體記憶體,ok可以用了。


思考3:

如果希望進程共用某一個虛擬記憶體地址0x80001000的資料, 那麼在需要共用的進程p1,p2的頁表中添加1個entries(0x80001000->0x3000)。

另外核心是天然的共用對象,所以才在每一個進程中頁表中設定核心空間頁表的一份拷貝。

如果有個傢伙特立獨行,建立n個關於核心空間的頁表,指向n個實體記憶體塊,那麼他就需要再在這n個實體記憶體中"鋪設"n分核心代碼和資料的副本(真是自找麻煩)。


思考4:

核心棧確實不適合共用(一個特殊的記憶體地區)。怎麼辦?像使用者空間棧一樣固定在某一個虛擬位址,安插頁表項entries指向不同的實體記憶體?顯然不行! 只有一個辦法,在核心空間內分配n個不重疊的空間出來。


思考5:

核心步入的時候最初的“核心棧”並不是真正的核心棧,這個棧是全域的,每個cpu一個,是過渡到真正的核心棧使用的。(http://bbs.pediy.com/archive/index.php?t-87518.html)


思考6:

獨立核心棧的情境, at first 我們分析一下如果共用一個核心棧會出現什麼情況,假設有A、B三個進程,A調用系統調用read(1,...)讀按鍵,此時正好又沒有按鍵,
所以A被阻塞在核心,此時核心調度B執行,此時B也調用一個系統調用被阻塞了,而此時按鍵事件到來,進程A被喚醒,A繼續執行。我們想想B進入核心
已經破壞了A進入核心的核心棧,那此時A能正常返回嗎?所以從上面分析A、B肯定是擁有各自的核心棧。此核心棧好像是和task_struct以前分配的
一共分配了3個頁面,除了task_struct佔得記憶體外,其餘的就是核心棧。而在x86上這個棧等指標儲存在TSS斷的SS0和Esp0中。(http://bbs.chinaunix.net/thread-1930753-1-1.html)


參考資料:

1, 核心棧的使用(http://tech.ddvip.com/2008-09/122095404362368.html)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.