Linux內核 ——進程管理之進程誕生(基於版本4.x)

《奔跑吧linux內核》3.1筆記,不足之處還望你們批評指正linux

進程是Linux內核最基本的抽象之一,它是處於執行期的程序。它不只侷限於一段可執行代碼(代碼段),還包括進程須要的其餘資源。在Linux內核中常被稱做任務。數據結構

線程被稱爲輕量級進程,是操做系統調度的最小單元,一般一個進程能夠擁有多個線程。app

進程和線程的區別在於進程擁有獨立的資源空間,而線程則共享進程的資源空間。函數

問題一:在內核中如何獲取當前進程的task_struct數據結構?spa

  內核有一個經常使用的常量current用於獲取當前進程task_struct數據結構,它利用了內核棧的特性。首先經過sp寄存器獲取當前內核棧的地址,對齊後獲取struct thread_info數據結構指針,最後經過thread_info->task成員獲取task_struct數據結構。圖1爲linux內核棧的結構圖。操作系統

圖1 內核棧線程

 

問題二:下面程序會打印幾個「_」?指針

int main(void){blog

  int i;進程

  for(i=0; i<2; i++){

    fork();

    printf("_\n");}

  wait(NULL);wait(NULL);

  return 0;}

   答案是6個「_」,具體思路如圖2所示。(i=0,調用一次fork後,父進程a建立子進程b,此後a和b進行打印,打印兩個「_」;後i=1,a和b均調用fork,a建立子進程a_1,b建立子進程b_1,4個進程執行打印操做,打印出四個「_」;i=2,返回)

圖2 fork解題思路

 

問題三:用戶空間進程的頁表是何時分配的,其中一級頁表何時分配?二級頁表呢?

   (此問有點疑問,暫且認爲一級頁表爲頁目錄項(pgd),二級頁表爲也表項(pte))

  對於內核來講,進程的「鼻祖」是idle進程,稱爲swapper進程;對於用戶空間來講,進程「鼻祖」是init進程,全部用戶空間進程都由init進程建立或派生。

  在mm_init()函數中,首先給新進程的mm_struct數據結構進行初始化,而後對mm_users,mm_count進行初始化,設置進程空間地址讀寫信號量,設置保護進程頁表的spinlock鎖,最後調用pgd_alloc()函數進行pgd頁表的分配工做。在pgd_alloc()函數中,調用pte_alloc_map()函數進行第0,第1個頁表的分配,此後在dup_mmap()函數中將父進程全部的VMA對應的pte頁表項複製到子進程對應的pte頁表項中。

問題四:請簡述fork,vfork和clone之間的區別?

   fork,vfork,clone的實現都是經過調用do_fork()函數實現的,只是函數調用不同。

  fork函數實現:do_fork(SIGCHLD,0,0,NULL,NULL);只使用SIGCHLD標誌位,在子進程終止後發送SIGCHLD信號通知父進程。fork是重量級調用,爲子進程創建了一個基於父進程的完整副本,而後子進程基於此運行。爲了減小工做量採用寫時複製技術(COW),子進程只複製父進程的頁表,不復制頁面內容。當子進程須要寫入新內容時,才觸發寫時複製機制,爲子進程建立一個副本。

  vfork函數實現:do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,0,0,NULL,NULL);它比fork多了兩個標誌位,分別爲CLONE_VFORK和CLONE_VM。CLONE_VFORK表示父進程會被掛起,直至子進程釋放虛擬內存資源。CLONE_VM表示父子進程運行在相同的內存空間中。

  clone函數實現:do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr);clone用於建立線程,而且參數經過寄存器從用戶空間傳遞下來,一般會指定新的棧地址(newsp)。

相關文章
相關標籤/搜索