Linux 建立多進程 & 線程時的進程棧段處理

來源:互聯網
上載者:User

 最近有日子沒寫部落格了,這段時間有點事忙活一陣子,好在已經接近尾聲。也該輪到投些時間好好研究下真刀真槍的東西,幹些有意義的事。這兩天抽時間繼續往下看了看 Linux 核心和 Unix 編程的書,邊看邊琢磨,想到個關於進程在 fork 子進程或 pthread 出 lwp 時父親進程的棧段是如何處理的問題,結合 Linux 核心的說明對這個問題有了明確的理解,在此做個筆記。大家也一起研究、分享下~

 

曆史上來說,*nix 裡的 C 程式進程由以下幾部分組成:

 

  1. 本文段。也有叫程式碼片段的。存放著 CPU 執行的機器指令。它一般是共用、唯讀。
  2. 初始化資料區段。存放著程式中明確賦初值的變數。
  3. 非初始化資料區段。也叫 bss ,存放著 C 函數之外的變數,核心會初始它為 0 填充。
  4. 棧段。存放 auto 變數或函數調用傳遞的資訊。包括傳回值、實參,調用者上下文(忽然想到,閉包變數會用這個傳遞嗎?請教 guru),這些變數會存在一個 stack frame 中。
  5. 堆段。用於 sbrk (malloc) 等動態記憶體分配的。

 

 

        這圖說明了這些段的典型的布局。在 x86 CPU 的 Linux 中棧底位於 0xc0000000 開始,該地址以上儲存的就是核心代碼了(那段線性地址直接映射到物理地址)。當我看到這裡的時候,困惑的問題是,在這種段結構中,當我們父進程產生多進程/線程的子進程時,linux 核心對這個父進程的 stack 段是怎麼處理了,來保證每個不同進程/線程中的方法調用時,用 stack 來傳遞的調用資訊不會混亂,怎麼保證競爭條件下的正確入/出棧順序?呵呵,現在看來當時的想法比較可笑了。正確理解如下所述。

 

*nix 有3種進程建立方式:

 

  1. fork。核心為父進程棄置站台,即子進程。傳統情況下,該子進程將獲得父進程完整複製,包括資料區段(初始化和bss 段)和堆棧段。但是,由於 fork 之後經常跟著就是 execve 系統調用,因此現在的 *nix 會使用 COW(寫時複製) 方式來 fork 子進程,也就是這些地區暫時不複製,並由核心將它們唯讀,當父/子進程對他們修改時,就將修改的部分儲存在本次修改操作的進程地址空間中,通常單位是一頁。核心為了提高效能,如果父子進程在同一顆 CPU 上的話呢(同 CPU 進程隊列),會在 TASK_RUNNING 進程鏈中將子進程放在放在父進程的前邊,這樣可減少不必要的 COW 開銷。此外還有一些其它屬性也將由子進程繼承,如實際、有效使用者/組 ID,會話 ID,工作目錄,環境,串連的共用儲存段,資源限制等等。
  2. lwp。輕量進程允許父子進程共用核心的在部分資料,頁表(可共用全域資料),檔案描述符表等。pthead 就是通過 lwp 實現的。
  3. vfork。apue2中將 vfork 單提了來,個人覺得實際和 fork 是一要的,只不過是簡版的。通過它建立的子進程能夠共用父進程記憶體位址空間,但為了避免父子混亂,子進程暫時阻塞了父進程執行,直到子進程退出父進程再在此基礎上繼續執行。

 

          實際上看到這裡,已經能夠很清楚的解釋我上面的疑問了,呵呵。fork 方式會獨立出父子進程,vfork 會順序執行。那麼 fork/lwp 的具體細節核心是怎麼做到的呢,繼續挖。

 

          Linux 通過 clone 系統調用來建立 lwp,而 clone、fork、vfork 都是由 do_fork 核心功能來統一處理完成的,而 do_fork 又是由 copy_process 函數來完成功能的。再看一眼上面我最初想到的問題,已經知道 fork 會出來兩個獨立的使用者進程空間,因此父子進程的棧段肯定不重複。但 lwp 怎麼保證棧段不重複的呢,就是通過 clone 系統調用的 child_stack、tls 和 flags 參數來控制的,詳細說明看文檔和核心源碼吧。Linux 中子進程的具體建立步驟說明可見《Understanding The Linux Kernel》 3th 的 P123 很詳盡有看起來也有力道,呵呵。

 

          現在關於這個 tls 還有沒理解的地方,在 GDT 中共有 3 個 TLS ,段選擇符 0x33 - 0x43(那也就是說只允許最多 3  個線程局部資料區段),這個 clone 的 tls 參數是傳遞的什麼值,是 GDT 中 tls 的段描述符地址嗎?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.