Linux------建立和終止進程

建立進程:數組

Linux建立兩個步驟的新處理:fork()和exec().其中fork建立當前進程的能力(父進程)副本,那個孩子。父子進程只有PID不一樣。在這以後,該系統具備兩個進程,運行相同的操做。父進程的內容將被複制。但是在Linux中運用了一種寫時複寫(copy on write)技術。使進程的建立更爲高效。接下來exec將讀取可運行文件加載地址空間中運行。這樣一個進程就建立好啦!函數

當中fork系統調用的入口點爲sys_fork,該函數和體系結構有關,任務是從處理器的寄存器中提取由用戶空間提供的信息。並且調用與體系結構無關的do_fork()函數,進行進程複製。spa

而後do_fork主要進行下面幾項工做,進行進程生成的實際工做:接口

1.調用copy_process複製進程。隊列

2.獲取新進程的PID進程

3.用wake_up_new_taskhuanxing喚醒子進程,即將它的task_struct加入到調度器隊列中,但這並不意味着它可以立刻運行。而是調度器此時可以選擇它運行。事務


當中進程的複製又包含下面幾個步驟:內存

1.檢查各類標識,相似於CLONE_FS(與父進程共享文件系統)等待,有些標識的組合是沒有意義的,因此需要檢查資源

2.調用dup_task_struct建立父進程task_struct的副本。父子進程的task_struct進程僅僅有核心棧態這個成員不一樣博客

3.檢查資源限制,因爲每個用戶能擁有的進程數是有限的,超過則要放棄建立進

4.調用接口函數sched_fork,以便使調度器對新進程進行設置。防止內核的其它不論什麼部分在進程設置完畢前調度進程

5.調用不少相似於copy_xyz的例程,複製和共享內核子系統的各類資源

6.設置各個ID和進程關係

這樣整個進程就複製結束啦!


exec()的實現,即用新代碼取代舊代碼。可啓動新程序。

該系統調用的入口點是和體系結構相關的sys_execve函數。但是該函數很是快將工做交給與系統結構無關的do_execve例程。該例程主要進行下面幾個工做:

1.打開可運行文件

2.調用bprm_init來處理若干管理性事務:生成mm_alloc管理進程地址空間。init_new_context初始化該實例。__bprm_mm_init創建初始的棧

3.調用prepare_binprm提供父進程的一些相關值

4.複製環境和參數數組內容

5.調用search_binary_handler,在do_execve結束時查找一種適當的二進制格式,用於所要運行的文件。而二進制格式處理程序用於將新程序的數據載入到舊的地址空間中

這樣。一個新的程序就開始運行啦!


進程的終結:

進程要終結的時候會調用exit()函數,只是和前面同樣,終於都仍是經過調用do_exit()這個函數來結束進程的。

簡單的說。就是將各個引用計數器減一。如有計數器歸0。則釋放對應的內存。

而後調用exit_notify()告知父進程爲子進程找養父,並把進程狀態設置爲EXIT_ZOMBIE.最後調用schedule()切換到其它進程。

自此該進程不會被再次調用。此時該進程佔用的內存僅爲內存棧。thread_info和task_struct。

當父進程檢測到殭屍進程提供的信息以後。將進程所持有的剩餘內存釋放。至此進程終結。

相關文章
相關標籤/搜索