日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

內(nèi)核棧與用戶棧 kernel thread

 WUCANADA 2013-07-15
Linux下每個用戶空間進(jìn)程(不是kernel thread)都有兩個堆棧,一個內(nèi)核棧,一個系統(tǒng)棧。
其中內(nèi)核棧在創(chuàng)建進(jìn)程或者線程(do_fork)是創(chuàng)建,在2.6內(nèi)核中,他的內(nèi)容如下:
union thread_union {
   struct thread_info thread_info;
   unsigned long stack[THREAD_SIZE/sizeof(long)];
};
由此可見,此內(nèi)核棧的高端用于作為堆棧,底端用于存放thread_info(不是task_struct)。此堆棧用于存放進(jìn)程在內(nèi)核時的 call frames或者接收到中斷時的現(xiàn)場狀態(tài)(pt_regs),在有些體系結(jié)構(gòu)下,也存放同步上下文切換時的狀態(tài)(switch_stack)。內(nèi)核棧不能動態(tài)增長。

用戶棧在進(jìn)程調(diào)用execve的時候(參見fs/binfmt_*.c文件中的load_binary函數(shù),大概是這個函數(shù))創(chuàng)建,對于用 clone創(chuàng)建的線程來說,它可以由用戶來指定,用戶棧和內(nèi)核沒有任何關(guān)系,它用于存放進(jìn)程在用戶空間時的call frames。用戶堆棧可以動態(tài)增長。

線程(英語:thread)是操作系統(tǒng)能夠進(jìn)行運算調(diào)度的最小單位。它被包含在進(jìn)程之中,是進(jìn)程中的實際運作單位。一條線程指的是進(jìn)程中一個單一順序的控制流,一個進(jìn)程中可以并發(fā)多個線程,每條線程并行執(zhí)行不同的任務(wù)。在Unix System VSunOS中也被稱為輕量進(jìn)程(lightweight processes),但輕量進(jìn)程更多指內(nèi)核線程(kernel thread),而把用戶線程(user thread)稱為線程。

線程是獨立調(diào)度和分派的基本單位。線程可以操作系統(tǒng)內(nèi)核調(diào)度的內(nèi)核線程,如Win32線程;由用戶進(jìn)程自行調(diào)度的用戶線程,如Linux Portable Thread;或者由內(nèi)核與用戶進(jìn)程,如Windows 7的線程,進(jìn)行混合調(diào)度。

同一進(jìn)程中的多條線程將共享該進(jìn)程中的全部系統(tǒng)資源,如虛擬地址空間,文件描述符信號處理等等。但同一進(jìn)程中的多個線程有各自的調(diào)用棧(call stack),自己的寄存器環(huán)境(register context),自己的線程本地存儲(thread-local storage)。

一個進(jìn)程可以有很多線程,每條線程并行執(zhí)行不同的任務(wù)。

每個進(jìn)程都有自己的 3 G 用戶空間,它們共享1GB的內(nèi)核空間。當(dāng)一個進(jìn)程從用戶空間進(jìn)入內(nèi)核空間時,它就不再有自己的進(jìn)程空間了.
對內(nèi)核線程的虛擬空間總結(jié)一下:
1、創(chuàng)建的時候:
父進(jìn)程是用戶進(jìn)程,則mm和active_mm均共享父進(jìn)程的,然后內(nèi)核線程一般調(diào)用daemonize
父進(jìn)程是內(nèi)核線程,則mm和active_mm均為NULL
總之,內(nèi)核線程的mm = NULL;進(jìn)程調(diào)度的時候以此為依據(jù)判斷是用戶進(jìn)程還是內(nèi)核線程。
2、進(jìn)程調(diào)度的時候
如果切換進(jìn)來的是內(nèi)核線程,則置active_mm為切換出去的進(jìn)程的active_mm;
如果切換出去的是內(nèi)核線程,則置active_mm為NULL。
linux在創(chuàng)建用戶任務(wù)的時候,給每個任務(wù)都分配了一個kernel modestack。一個運行在用戶態(tài)的任務(wù)如果被一個IRQ打斷,中斷處理要做一次堆棧切換。這時linux好像使用了任務(wù)的kernel modestack,也就是說linux系統(tǒng)中沒有一個唯一的系統(tǒng)堆棧,而是每一個任務(wù)都有一個系統(tǒng)堆棧,中斷處理的棧使用的就是被打斷任務(wù)的系統(tǒng)堆棧。 內(nèi)核線程也是進(jìn)程,只不過沒有自己的用戶空間,但task_struct和內(nèi)核堆棧還是得有的,要不怎么運行呢?
[1.內(nèi)核在主動進(jìn)行進(jìn)程調(diào)度時,可以自己設(shè)置將要投入運行進(jìn)程的 sp0為TSS段中的sp0,則該用戶進(jìn)程在進(jìn)入內(nèi)核后使用的是它自身的系統(tǒng)堆棧,但如果cpu運行在某一用戶進(jìn)程時,而為另一用戶進(jìn)程服務(wù)的外部中斷發(fā) 生了,在進(jìn)入內(nèi)核后使用的是當(dāng)前用戶進(jìn)程的系統(tǒng)堆棧,還是中斷服務(wù)的另一用戶進(jìn)程的系統(tǒng)堆棧呢?
2操作系統(tǒng)映象是否擁有自己的堆??臻g?還是利用用戶進(jìn)程的系統(tǒng)堆棧?
回答: 1。外部中斷不是為某個用戶進(jìn)程服務(wù)的,是為整個操作系統(tǒng)服務(wù)的,它始終用當(dāng)前進(jìn)程的核心堆棧。??????中斷棧

從《深入Linux內(nèi)核構(gòu)架》中可以知道:內(nèi)核在IA-32平臺上,早期(2.6.36及之前)內(nèi)核如 果配置了4K內(nèi)核棧(CONFIG_4KSTACKS)(默認(rèn)是8K),對于常規(guī)的內(nèi)核工作以及IRQ處理例程共用這個棧來說似乎有點不夠用,所有引入了 兩個棧:硬件IRQ棧和軟件IRQ棧。在這種情況下,當(dāng)內(nèi)核進(jìn)入中斷之后,檢測自己所在的棧是內(nèi)核棧還是中斷棧。如果是中斷棧(中斷嵌套情況)就去執(zhí)行中 斷例程;如果是內(nèi)核棧就切換到中斷棧,同時復(fù)制當(dāng)前內(nèi)核棧中的部分thread_info數(shù)據(jù)到中斷棧。
   但是2.6.36之后的內(nèi)核就不再有4K內(nèi)核棧的配置,對于IA-32統(tǒng)一使用8K內(nèi)核棧,并總是使用兩個獨立的8K中斷棧。這樣的改變應(yīng)該是由于計算機(jī)性能的提高、內(nèi)存的擴(kuò)大(4G內(nèi)存已經(jīng)很平常,16G、32G內(nèi)存也已不新鮮)以及軟件的復(fù)雜度提高(對棧的需求增加)。


跟蹤了ARM構(gòu)架的內(nèi)核代碼發(fā)現(xiàn)其中(arch/arm/kernel/irq.c)并沒有和x86類似的棧轉(zhuǎn)換設(shè)計。也就是說:ARM并沒有獨立的中斷棧,中斷共用當(dāng)前進(jìn)程的內(nèi)核棧。

Linux 0.11 系統(tǒng)中共使用了四種堆棧。
一種是系統(tǒng)初始化時臨時使用的堆棧;
一種是供內(nèi)核程序自己使用的堆棧(內(nèi)核堆棧),只有一個,位于系統(tǒng)地址空間固定的位置,也是后來任務(wù)0 的用戶態(tài)堆棧;
另一種是每個任務(wù)通過系統(tǒng)調(diào)用,執(zhí)行內(nèi)核程序時使用的堆棧,我們稱之為任務(wù)的內(nèi)核態(tài)堆棧,每個任務(wù)都有自己獨立的內(nèi)核態(tài)堆棧;
最后一種是任務(wù)在用戶態(tài)執(zhí)行的堆棧,位于任務(wù)(進(jìn)程)地址空間的末端。

也就是說,schedule()的時候發(fā)生上下文切換,何時調(diào)用schedule()?
1.程序員顯示調(diào)用schedule().
2.內(nèi)核提供need_reshed標(biāo)志表明是否需要重新執(zhí)行一次調(diào)度,每個進(jìn)程都包含一個need_reshed標(biāo)志(2.6中移入thread_info某個特殊變量的一位)。
1)當(dāng)某個進(jìn)程耗盡時間片時,scheduler_tick()會設(shè)置這個標(biāo)志。
2)當(dāng)一個優(yōu)先級高的程序進(jìn)入可執(zhí)行狀態(tài)的時候,try_to_wake_up()也會設(shè)置這個標(biāo)志。 3)再返回用戶空間以的時候,內(nèi)核會檢查need_reshed。 4)從中斷返回的時候,內(nèi)核會檢查need_reshed

實時調(diào)度策略
Linux提供了兩種實時調(diào)度策略:SCHED_FIFO和SCHED_RR。普通、非實時的調(diào)度策略是SCHED_NORMAL。
SCHED_FIFO級的進(jìn)程會比任何SCHED_NORMAL級的進(jìn)程都先得到調(diào)度,一旦一個SCHED_FIFO級進(jìn)程處于可執(zhí)行狀態(tài),就會一直執(zhí) 行,直到它自己受阻塞或顯式地釋放處理器。它不基于時間片,可以一直執(zhí)行下去,只有較高優(yōu)先級的SCHED_FIFO或者SCHED_RR任務(wù)才能搶占 SCHED_FIFO任務(wù)。
SCHED_RR是帶時間片的SCHED_FIFO,是一種實時輪流調(diào)度算法。
這兩種實時算法實現(xiàn)的都是靜態(tài)優(yōu)先級,內(nèi)核不為之計算動態(tài)優(yōu)先級。
Linux的實時調(diào)度算法提供一種軟實時的工作方式,內(nèi)核調(diào)度進(jìn)程,盡力使進(jìn)程在它的限定時間到來前運行,但內(nèi)核不保證總能滿足這些進(jìn)程的要求。



    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多