深入理解linux內核之(二)進程
程序是靜態的,進程是正在執行的程序的一個實例,一個程序可以由多個進程組成.進程是資源分配的實體.
在進程被創建出來之後,該子進程幾乎和父進程一樣.子進程複製了父進程的地址空間,從fork()之後的第一條指令開始執行,和父進程有同樣的程序可執行代碼(exec調用除外).盡管子進程和父進程具有同樣的程序執行代碼,但是子進程擁有自己的stack和heap,因此,子進程對數據的修改對父進程來說是不可見的.
前麵說到子進程複製了父進程的地址空間以及數據.那麼,這種複製遵循 寫時複製(COW) 的原則.當子進程創建之後,內核將父進程的數據標記為read-only隻讀.一開始子進程是共享父進程的數據的,隻有當子進程需要對數據作出修改(寫)的時候,才會將相關數據從父進程複製到子進程的地址空間.
盡管如此,在用戶空間子進程還是從父進程繼承了很多東西:
- 父進程打開的文件,包括文件描述符,offset
- Real user ID, real group ID, effective ID, effective group ID
- 追加的group ID
- 進程組ID
- Session 會話ID
- 控製終端
- Set-user-ID, set-group-ID 標誌
- 當前的工作目錄
- Root 目錄
- 創建文件的模式掩碼
指的是創建一個文件時,給文件的最基本的權限.比如055.
- 信號mask以及信號的處理方式(handle)
子進程擁有和父進程相同的信號處理方式.例如父進程忽略了SIGINT,子進程也 了SIGINT信號,當然,子進程可以更改該處理方式.
- 打開文件的close-on-exec標誌
- 環境變量
- 共享內存段
- 內存映射
- 資源限製變量
子進程和父進程不同之處:
- fork()的返回值不同
fork()在父進程中返回子進程進程號,在子進程中返回0;
- 進程號不同
- 父進程ID不同
- 父進程的文件鎖沒有被子進程繼承
- 掛起的鬧鍾被清除
- 信號集被設置為空
新版本的Linux(2.6)內核中,已經能夠很好的對多線程進行支持了, 在較老版本的Linux當中,將線程當做普通進程或者交付給用戶空間處理線程.對於現行的新Linux版本提出了一個輕量級進程的概念.內核中,用一個輕量級的進程代表一個線程,並將用戶空間的線程和內核中的輕量級進程進行關聯,從而可以使得用戶空間線程得到管理和調度.輕量級進程共享父進程的數據.這樣一來,可以達到很好的對多線程進行支持.
每一個進程在內核中都有一個task_struct結構體來表示,該結構體包含了一個進程所需的全部信息.並將這些task_struct放到一個雙向鏈表task list中.
關於task_struct相關結構我在這裏就不贅述,這方麵的資料參考Linux Kernel development
版權申明:
轉載文章請注明原文出處https://blog.csdn.net/feiyinzilgd/archive/2010/09/15/5885640.aspx
並請聯係譚海燕本人或者前往譚海燕個人主頁留言
最後更新:2017-04-02 06:51:25