Linux內(nèi)核深度解析-進程管理-讀書筆記

進程
Linux內(nèi)核把進程稱為任務(wù)(task)稳其,進程的虛擬地址空間分為用戶虛擬地址空間和內(nèi)核虛擬地址空間,所有進程共享內(nèi)核虛擬地址空間炸卑,每個進程有獨立的用戶虛擬地址空間既鞠。
進程有兩種特殊形式:沒有用戶虛擬地址空間的進程稱為內(nèi)核線程,共享用戶虛擬地址空間的進程稱為用戶線程盖文,通常在不會引起混淆的情況下把用戶線程簡稱為線程嘱蛋。共享同一個用戶虛擬地址空間的所有用戶線程組成一個線程組。

命名空間
Linux的命名空間機制提供了一種資源隔離的解決方案五续。PID,IPC,Network等系統(tǒng)資源不再是全局性的洒敏,而是屬于特定的Namespace。Linux Namespace機制為實現(xiàn)基于容器的虛擬化技術(shù)提供了很好的基礎(chǔ)疙驾,LXC(Linux containers)就是利用這一特性實現(xiàn)了資源的隔離凶伙。不同Container內(nèi)的進程屬于不同的Namespace,彼此透明它碎,互不干擾函荣。
Namespace是對全局系統(tǒng)資源的一種封裝隔離,使得處于不同namespace的進程擁有獨立的全局系統(tǒng)資源扳肛,改變一個namespace中的系統(tǒng)資源只會影響當(dāng)前namespace里的進程偏竟,對其他namespace中的進程沒有影響。

進程有以下標識符
(1)進程標識符(pid):進程所屬的進程號命名空間到根的每層命名空間敞峭,都會給進程分配一個標識符踊谋。
(2)線程組標識符(tgid):多個共享用戶虛擬地址空間的進程組成一個線程組,線程組中的主進程稱為組長旋讹,線程組標識符就是組長的進程標識符殖蚕。當(dāng)調(diào)用系統(tǒng)調(diào)用clone傳入標志CLONE_THREAD以創(chuàng)建新進程時,新進程和當(dāng)前進程屬于一個線程組沉迹。進程描述符的成員tgid存放線程組標識符睦疫,成員group_leader指向組長的進程描述符。
(3)進程組標識符:多個進程可以組成一個進程組鞭呕,進程組標識符是組長的進程標識符蛤育。進程可以使用系統(tǒng)調(diào)用setpgid創(chuàng)建或者加入一個進程組。會話和進程組被設(shè)計用來支持shell作業(yè)控制,shell為執(zhí)行單一命令或者管道的進程創(chuàng)建一個進程組瓦糕。進程組簡化了向進程組的所有成員發(fā)送信號的操作底洗。
(4)會話標識符(sid):多個進程組可以組成一個會話。當(dāng)進程調(diào)用系統(tǒng)調(diào)用setsid的時候咕娄,創(chuàng)建一個新的會話亥揖,會話標識符是該進程的進程標識符。創(chuàng)建會話的進程是會話的首進程圣勒。

線程組結(jié)構(gòu):一個線程組的所有線程鏈接在一條線程鏈表上费变,頭節(jié)點是組長的成員thread_group,鏈表節(jié)點是線程的成員thread_group圣贸。線程的成員group_leader指向組長的進程描述符挚歧,成員tgid是線程組標識符,成員pid存放自己的進程標識符吁峻。

內(nèi)核線程創(chuàng)建過程:在Linux內(nèi)核中滑负,新進程是從一個已經(jīng)存在的進程復(fù)制出來的。內(nèi)核使用靜態(tài)數(shù)據(jù)構(gòu)造出0號內(nèi)核線程锡搜,0號內(nèi)核線程分叉生成1號內(nèi)核線程和2號內(nèi)核線程(kthreadd線程)橙困。1號內(nèi)核線程完成初始化以后裝載用戶程序,變成1號進程耕餐,其他進程都是1號進程或者它的子孫進程分叉生成的凡傅;其他內(nèi)核線程是kthreadd線程分叉生成的。

創(chuàng)建新的進程:
(1)fork(分叉):子進程是父進程的一個副本肠缔,采用了寫時復(fù)制的技術(shù)夏跷。
(3)clone(克隆):可以精確地控制子進程和父進程共享哪些資源明未。這個系統(tǒng)調(diào)用的主要用處是可供pthread庫用來創(chuàng)建線程槽华。
clone是功能最齊全的函數(shù),參數(shù)多趟妥,使用復(fù)雜猫态,fork是clone的簡化函數(shù)。

創(chuàng)建子進程的流程(_do_fork)
(1)調(diào)用函數(shù)copy_process以創(chuàng)建新進程披摄。
(2)如果參數(shù)clone_flags設(shè)置了標志CLONE_PARENT_SETTID亲雪,那么把新線程的進程標識符寫到參數(shù)parent_tidptr指定的位置。
(3)調(diào)用函數(shù)wake_up_new_task以喚醒新進程疚膊。
(4)如果是系統(tǒng)調(diào)用vfork义辕,那么當(dāng)前進程等待子進程裝載程序。

copy_process流程
1.調(diào)用 dup_task_struct 復(fù)制當(dāng)前的 task_struct
2.檢查進程數(shù)是否超過限制
3.初始化自旋鎖寓盗、掛起信號灌砖、CPU 定時器等
4.調(diào)用 sched_fork 初始化進程數(shù)據(jù)結(jié)構(gòu)璧函,新進程設(shè)置優(yōu)先級、調(diào)度策略基显、運行CPU等參數(shù)蘸吓,并把進程狀態(tài)設(shè)置為 TASK_RUNNING
5.復(fù)制所有進程信息,包括文件系統(tǒng)续镇、信號處理函數(shù)美澳、信號销部、內(nèi)存管理等
6.調(diào)用 copy_thread_tls 初始化子進程內(nèi)核棧
7.為新進程分配并設(shè)置新的 pid

函數(shù)dup_task_struct:函數(shù)dup_task_struct為新進程的進程描述符分配內(nèi)存摸航,把當(dāng)前進程的進程描述符復(fù)制一份(及復(fù)制task_struct),為新進程分配內(nèi)核棧舅桩。

函數(shù)wake_up_new_task:負責(zé)喚醒剛剛創(chuàng)建的新進程酱虎,把新進程的狀態(tài)從TASK_NEW切換到TASK_RUNNING,為新進程選擇一個負載最輕的處理器擂涛。把新進程插入運行隊列读串。

裝載程序
如果程序的main函數(shù)被定義為下面的形式,參數(shù)指針數(shù)組和環(huán)境指針數(shù)組可以被程序的main函數(shù)訪問:
int main(int argc,char *argc[],char *envp[]);
最終都調(diào)用函數(shù)do_execveat_common
1.調(diào)用open_exec()查找并打開二進制文件
2.調(diào)用sched_exec()找到最小負載的CPU撒妈,用來執(zhí)行該二進制文件
3.調(diào)用bprm_mm_init()創(chuàng)建進程的內(nèi)存地址空間恢暖,為新程序初始化內(nèi)存管理.并調(diào)用init_new_context()檢查當(dāng)前進程是否使用4.自定義的局部描述符表;如果是狰右,那么分配和準備一個新的LDT
5.調(diào)用prepare_binprm()檢查該二進制文件的可執(zhí)行權(quán)限杰捂;最后,kernel_read()讀取二進制文件的頭128字節(jié)(這些字節(jié)用于識別二進制文件的格式及其他信息棋蚌,后續(xù)會使用到)
6.調(diào)用copy_strings_kernel()從內(nèi)核空間獲取二進制文件的路徑名稱
7.調(diào)用copy_string()從用戶空間拷貝環(huán)境變量和命令行參數(shù)
8.至此嫁佳,二進制文件已經(jīng)被打開,struct linux_binprm結(jié)構(gòu)體中也記錄了重要信息, 內(nèi)核開始調(diào)用exec_binprm執(zhí)行可執(zhí)行程序
釋放linux_binprm數(shù)據(jù)結(jié)構(gòu)谷暮,返回從該文件可執(zhí)行格式的load_binary中獲得的代碼

每種二進制格式都表示為下面的數(shù)據(jù)結(jié)構(gòu)


binfmts.png

ELF文件:ELF(Executable and Linkable Format)是可執(zhí)行與可鏈接格式蒿往,主要有以下4種類型。
? 目標文件(object file)湿弦,也稱為可重定位文件(relocatable file)瓤漏,擴展名是“.o”,多個目標文件可以鏈接生成可執(zhí)行文件或者共享庫颊埃。
? 可執(zhí)行文件(executable file)蔬充。
? 共享庫(shared object file),擴展名是“.so”竟秫。
? 核心轉(zhuǎn)儲文件(core dump file)娃惯。

只有ELF首部的位置是固定的,其余各部分的位置和大小由ELF首部的成員決定肥败。


elf.png

程序首部表就是我們所說的段表(segment table)趾浅,段(segment)是從運行的角度描述愕提,節(jié)(section)是從鏈接的角度描述,一個段包含一個或多個節(jié)皿哨。在不會混淆的情況下,我們通常把節(jié)稱為段证膨,例如代碼段(text section)如输,不稱為代碼節(jié)。

加載elf文件流程load_elf_binary
1.填充并且檢查目標程序ELF頭部
2.load_elf_phdrs加載目標程序的程序頭表
3.如果需要動態(tài)鏈接, 則尋找和處理解釋器段
4.檢查并讀取解釋器的程序表頭
5.flush_old_exec終止線程組中的其他線程
6.setup_new_exec設(shè)置內(nèi)存映射布局
7.setup_arg_pages更新用戶棧的標志位和訪問位央勒,把用戶棧移到最終位置不见,并且擴大用戶棧
8.把所有可加載段映射到進程的虛擬地址空間
9.setbrk把未初始化數(shù)據(jù)段映射到進程的用戶虛擬地址空間,并設(shè)置堆的起始地址
10.得到程序的入口
11.create_elf_tables依次把傳遞ELF解釋器信息的輔助向量崔步、環(huán)境指針數(shù)組envp稳吮、參數(shù)指針數(shù)組argv和參數(shù)個數(shù)argc壓到進程用戶棧
12.start_thread開始程序

裝載腳本程序
腳本程序的主要特征是:前兩字節(jié)是“#!”,后面是解釋程序的名稱和參數(shù)井濒。解釋程序用來解釋執(zhí)行腳本程序灶似。
源文件“fs/binfmt_script.c”定義的函數(shù)load_script負責(zé)裝載腳本程序,主要步驟如下瑞你。

load_script.png

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酪惭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子者甲,更是在濱河造成了極大的恐慌春感,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件过牙,死亡現(xiàn)場離奇詭異甥厦,居然都是意外死亡,警方通過查閱死者的電腦和手機寇钉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門刀疙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人扫倡,你說我怎么就攤上這事谦秧。” “怎么了撵溃?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵疚鲤,是天一觀的道長。 經(jīng)常有香客問我缘挑,道長集歇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任语淘,我火速辦了婚禮诲宇,結(jié)果婚禮上际歼,老公的妹妹穿的比我還像新娘。我一直安慰自己姑蓝,他們只是感情好鹅心,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著纺荧,像睡著了一般旭愧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宙暇,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天输枯,我揣著相機與錄音,去河邊找鬼客给。 笑死用押,一個胖子當(dāng)著我的面吹牛肢簿,可吹牛的內(nèi)容都是我干的靶剑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼池充,長吁一口氣:“原來是場噩夢啊……” “哼桩引!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起收夸,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤坑匠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后卧惜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體厘灼,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年咽瓷,在試婚紗的時候發(fā)現(xiàn)自己被綠了设凹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡茅姜,死狀恐怖闪朱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情钻洒,我是刑警寧澤奋姿,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站素标,受9級特大地震影響称诗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜头遭,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一寓免、第九天 我趴在偏房一處隱蔽的房頂上張望退腥。 院中可真熱鬧,春花似錦再榄、人聲如沸狡刘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嗅蔬。三九已至,卻和暖如春疾就,著一層夾襖步出監(jiān)牢的瞬間澜术,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工猬腰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鸟废,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓姑荷,卻偏偏與公主長得像盒延,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子鼠冕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容