Linux內(nèi)核學(xué)習(xí)006——進(jìn)程管理(二)

Linux內(nèi)核學(xué)習(xí)006——進(jìn)程管理(二)

之前提到在Linux內(nèi)核中把進(jìn)程(process)叫做任務(wù)(task),因此我會交替使用這兩個術(shù)語怠惶,本質(zhì)上它們指的是同一個東西耀态。

進(jìn)程描述符及任務(wù)結(jié)構(gòu)

內(nèi)核中把進(jìn)程的列表存放在任務(wù)隊列(一個雙向循環(huán)鏈表)中轮傍,鏈表中的的每一項都是類型為task_struct的結(jié)構(gòu)體,叫做進(jìn)程描述符首装。該結(jié)構(gòu)體描述了一個進(jìn)程的所有信息创夜,其定義位于linux-2.6.34/include/linux/sched.h中的1170行∠陕撸可以在之前安裝的虛擬機CentOS6上下載對應(yīng)源碼查看驰吓,或者使用在線網(wǎng)站查看:https://elixir.bootlin.com/linux/v2.6.34/source/include/linux/sched.h#L1170

如下所示:

2019-02-01_201527.png

task_struct結(jié)構(gòu)體比較大系奉,在32位機器上檬贰,大概1.7KB。

任務(wù)列表大致如下所示:

figure_3.1.png

分配進(jìn)程描述符

內(nèi)核通過slab分配器分配task_struct結(jié)構(gòu)體缺亮,這樣可以達(dá)到對象復(fù)用和緩存著色的目的翁涤。

這里的slab分配器是內(nèi)核分配內(nèi)存的一種方法,內(nèi)核內(nèi)存的分配通常是從空閑的內(nèi)存池中獲取的,主要有兩種方式:Buddy系統(tǒng)和slab分配葵礼。

slab其實就是一個或多個物理上連續(xù)的內(nèi)存頁号阿。每個內(nèi)核數(shù)據(jù)結(jié)構(gòu)都有一個高速緩存(cache),比如進(jìn)程描述符鸳粉。每個cache都含有一個或多個slab扔涧。其關(guān)系如下所示:

2019-02-01_203426.png

在2.6以前的內(nèi)核中,每個進(jìn)程的task_struct存放在其內(nèi)核棧的尾端赁严,這樣可以方便類似于x86這樣的寄存器較少的硬件體系結(jié)構(gòu)可以通過棧指針直接計算出其位置扰柠,而避免使用額外的寄存器記錄。在使用slab分配器動態(tài)生成task_struct后疼约,只需要在棧底(向下增長的棧)或棧頂(向上增長的棧)創(chuàng)建一個struct thread_info記錄即可卤档。

figure_3.2.png

對于x86體系,struct thread_info定義在linux-2.6.34/arch/x86/include/asm/thread_info.h:26行程剥。其具體定義如下:

struct thread_info {
        struct task_struct      *task;          /* main task structure */
        struct exec_domain      *exec_domain;   /* execution domain */
        __u32                   flags;          /* low level flags */
        __u32                   status;         /* thread synchronous flags */
        __u32                   cpu;            /* current CPU */
        int                     preempt_count;  /* 0 => preemptable,
                                                   <0 => BUG */
        mm_segment_t            addr_limit;
        struct restart_block    restart_block;
        void __user             *sysenter_return;
#ifdef CONFIG_X86_32
        unsigned long           previous_esp;   /* ESP of the previous stack in
                                                   case of nested (IRQ) stacks
                                                */
        __u8                    supervisor_stack[0];
#endif
        int                     uaccess_err;
};

這樣劝枣,每個任務(wù)的thread_info結(jié)構(gòu)在其內(nèi)核棧的尾端分配,thread_info中的task指針指向?qū)嶋Htask_struct织鲸。

進(jìn)程描述符的存放

內(nèi)核通過一個唯一的進(jìn)程標(biāo)識符PID來標(biāo)識每個進(jìn)程舔腾,PID是類型位pid_t類型的整數(shù)(對于x86而言,就是int類型的別名)搂擦。為了與老版本的系統(tǒng)兼容稳诚,PID最大值位short int的最大值32768(可以增加到最大400萬左右)。pid存放在task_struct結(jié)構(gòu)體中瀑踢。

這個最大值實際上就是系統(tǒng)中允許同時存在的進(jìn)程的最大數(shù)目扳还,如果需要更大的值可以修改/proc/sys/kernel/pid_max提高。

在內(nèi)核中橱夭,訪問任務(wù)通常使用指向其task_struct的指針完成的氨距。而實際上,大多數(shù)內(nèi)核代碼直接通過處理struct task_struct完成的棘劣。因此俏让,能夠快速查找當(dāng)前正在執(zhí)行的任務(wù)的進(jìn)程描述符是很有用的,這是通過current宏完成的茬暇。這個宏的實現(xiàn)必須獨立于硬件體系結(jié)構(gòu):

  • 某些體系結(jié)構(gòu)在寄存器中保存指向當(dāng)前正在運行的進(jìn)程的task_struct結(jié)構(gòu)的指針首昔,從而實現(xiàn)高效訪問
  • 其他體系結(jié)構(gòu),例如x86糙俗,利用了存儲在內(nèi)核堆棧上的struct thread_info以計算thread_info的位置以及隨后的task_struct沙廉。

在PowerPC上,當(dāng)前的task_struct是保存在一個寄存器上的臼节。PowerPC有足夠多的寄存器,可以這樣加快訪問速度。

在x86系統(tǒng)上网缝,current把棧指針的后13個有效位屏蔽巨税,以此來計算thread_info的偏移。 該操作通過current_thread_info()函數(shù)完成粉臊。該函數(shù)位于linux2.6.34//arch/x86/include/asm/thread_info.h#L184草添。

具體代碼如下:

/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
{
    return (struct thread_info *)
        (current_stack_pointer & ~(THREAD_SIZE - 1));
}

其匯編代碼為(這里假設(shè)棧大小為8KB,若為4KB扼仲,則應(yīng)用4096代替8192):

movl $-8192, %eax
andl %esp, %eax

之后通過thread_info的task指針就可以獲取task_struct的地址了,current_thread_info()->task。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末育灸,一起剝皮案震驚了整個濱河市号坡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌矗愧,老刑警劉巖灶芝,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異唉韭,居然都是意外死亡夜涕,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門属愤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來女器,“玉大人,你說我怎么就攤上這事住诸〖莸ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵只壳,是天一觀的道長俏拱。 經(jīng)常有香客問我,道長吼句,這世上最難降的妖魔是什么锅必? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮惕艳,結(jié)果婚禮上搞隐,老公的妹妹穿的比我還像新娘。我一直安慰自己远搪,他們只是感情好劣纲,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谁鳍,像睡著了一般癞季。 火紅的嫁衣襯著肌膚如雪劫瞳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天绷柒,我揣著相機與錄音志于,去河邊找鬼。 笑死废睦,一個胖子當(dāng)著我的面吹牛伺绽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嗜湃,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼奈应,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了购披?” 一聲冷哼從身側(cè)響起杖挣,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎今瀑,沒想到半個月后程梦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡橘荠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年屿附,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哥童。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡挺份,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贮懈,到底是詐尸還是另有隱情匀泊,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布朵你,位于F島的核電站各聘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏抡医。R本人自食惡果不足惜躲因,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望忌傻。 院中可真熱鬧大脉,春花似錦、人聲如沸水孩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俘种。三九已至秤标,卻和暖如春绝淡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抛杨。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工够委, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人怖现。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像玉罐,于是被迫代替她去往敵國和親屈嗤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348

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