Linux學習記錄之進程(二)

3 線程在Linux中的實現

Linux中不區分線程和進程,線程僅僅被視爲一個域其他進程共享某些資源的進程。

線程的創建和普通進程的創建過程類似,只不過需要在調用clone()的時候傳遞一些參數來指明需要共享的資源:clone(CLONE_VM, CLONE_FS,CLONE_FILES,0)

參數列表如下:


內核線程

內核經常需要在後天運行一些任務,這可以通過內核線程來完成。內核線程與普通線程的區別在於沒有獨立的地址空間,它的mm指針設置爲NULL。他們只在內核空間運行

4 進程終結

一般進程的西溝發生在它調用exit()之後,既可能顯式的調用這個系統調用,也可能隱式的從某某個程序的主函數返回。不管進程是如何終結的,該任務大部分都要考do_exit()來完成,它要做下面這些繁瑣的工作:

1、首先,將task_struct中的標誌成員設置爲PF_EXITING。

2、其次,調用del_timer_sync()刪除任意內核定時器。根據返回的記過,它確保沒有定時器在排隊,也沒有定時器處理程序在運行。

3、如果BSD的進程記賬功能是開啓的,do_exit()調用acct_process()來輸出記賬信息。

4、然後調用exit_mm()函數放棄進程佔用的mm_struct,如果沒有別的進程使用它們(也就是說沒有被共享),就徹底釋放它們。

5、接下來調用exit_sem()函數。如果進程排隊等候IPC信號,它則離開隊列。

6、調用——exit_files()、_exit_fs()、exit_namespace()和exit_sighand(),以分別遞減文件描述符、文件系統數據、進程命名空間和信號處理函數的引用計數。如果其中某些引用計數的數值降爲零,那麼就代表沒有進程在使用相應的資源,此時可以釋放。

7、接着把存放在task_struct的exit_code成員中的任務退出代碼置爲exit()提供的代碼中,或者去完成任何其他由該內核機制規定的退出動作。退出代碼存放在這裏共父進程隨時檢索。

8、調用exit_notify()向父進程發送信號,將子進程的父進程重新設置爲線程組中的其他線程或init進程,並把進程狀態設成TASK_ZOMBIE。

9、最後,do_exit()調用schedule()切換到其他進程。因爲處於TASK_ZOMBIE狀態的進程不會再被調度,所以這是進程所執行的最後一段代碼。

這是進程處於不可運行的狀態,並且佔有內核棧、thread_info結構和task_struct結構。此時進程存在的唯一目的就是向他的父進程提供信息。父進程檢索到信息後,或者通知內核那是無關的信息後,由進程所持有的剩餘內存也被釋放,歸還給系統使用。

如果父進程在子進程之前退出,那麼要爲子進程重新找個父進程,可以使init進程。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章