標籤:c a 檔案 使用 資料 linux
在Linux中,進程的建立由系統調用fork和vfork完成。它們產生一個子進程並且子進程是父進程的一個複製品。
Fork系統調用對應的kernel函數是sys_fork,此函數簡單的調用kernel函數do_fork。一個簡化版的do_fork執行如下:
(1)alloc_pid()。給新的進程分配一個新的pid,即進程號
(2)copy_process()此函數會做fork的大部分事情,它主要完成講父進程的運行環境複製到新的子進程,比如訊號處理、檔案描述符和進程的代碼資料等。
(3)wake_up_new_task()。計算此進程的優先順序和其他調度參數,將新的進程加入到進程調度隊列並設此進程為可被調度的,以後這個進程可以被進程調度模組調度執行。
簡化的copy_process()流程:
(1) dup_task_struct()。分配一個新的進程式控制制塊,包括新進程在kernel中的堆棧。新的進程式控制制塊會複製父進程的進程式控制制塊,但是因為每個進程都有一個kernel堆棧,新進程的堆棧將被設定成新分配的堆棧。
(2)初始化一些新進程的統計資訊,如此進程的已耗用時間
(3)copy_semundo()複製父進程的semaphore undo_list到子進程。
(4)copy_files()、copy_fs()。複製父進程檔案系統相關的環境到子進程
(5)copy_sighand()、copy_signal()。複製父進程訊號處理相關的環境到子進程。
(6)copy_mm()。複製父進程記憶體管理相關的環境到子進程,包括頁表、地址空間和代碼資料。
(7)copy_thread()。設定子進程的執行環境,如子進程運行時各CPU寄存器的值、子進程的kernel棧的起始地址。
(8)sched_fork()。設定子進程調度相關的參數,即子進程的運行CPU、初始時間片長度和靜態優先順序等。
(9)將子進程加入到全域的進程隊列中
(10)設定子進程的進程組ID和對話期ID等。
簡單的說,copy_process()就是將父進程的運行環境複製到子進程並對某些子進程特定的環境做相應的調整。
應用程式使用系統調用exit()來結束一個進程,此系統調用接受一個退出原因代碼,父進程可以使用wait()系統調用來擷取此代碼,從而知道子進程退出的原因。對應到kernel,此系統調用sys_exit_group(),它的基本流程如下:
(1)將訊號SIGKILL加入到其他線程的訊號隊列中,並喚醒這些線程。
(2)此線程執行do_exit()來退出。
do_exit()完成線程退出的任務,其主要功能是將線程佔用的系統資源釋放,do_exit()的基本流程如下:
(1)將進程記憶體管理相關的資源釋放
(2)將進程ICP semaphore相關資源釋放
(3)__exit_files()、__exit_fs()。將進程檔案管理相關的資源釋放。
(4)exit_thread()。只要目的是釋放平台相關的一些資源。
(5)exit_notify()。在Linux中進程退出時要將其退出的原因告訴父進程,父進程調用wait()系統調用後會在一個等待隊列上睡眠。
(6)schedule()。調用進程調度器,因為此進程已經退出,切換到其他進程。