小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

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

 WUCANADA 2013-07-15
Linux下每個(gè)用戶空間進(jìn)程(不是kernel thread)都有兩個(gè)堆棧,一個(gè)內(nèi)核棧,一個(gè)系統(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)核時(shí)的 call frames或者接收到中斷時(shí)的現(xiàn)場狀態(tài)(pt_regs),在有些體系結(jié)構(gòu)下,也存放同步上下文切換時(shí)的狀態(tài)(switch_stack)。內(nèi)核棧不能動態(tài)增長。

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

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

線程是獨(dú)立調(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)程中的多個(gè)線程有各自的調(diào)用棧(call stack),自己的寄存器環(huán)境(register context),自己的線程本地存儲(thread-local storage)。

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

每個(gè)進(jìn)程都有自己的 3 G 用戶空間,它們共享1GB的內(nèi)核空間。當(dāng)一個(gè)進(jìn)程從用戶空間進(jìn)入內(nèi)核空間時(shí),它就不再有自己的進(jìn)程空間了.
對內(nèi)核線程的虛擬空間總結(jié)一下:
1、創(chuàng)建的時(shí)候:
父進(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)度的時(shí)候以此為依據(jù)判斷是用戶進(jìn)程還是內(nèi)核線程。
2、進(jìn)程調(diào)度的時(shí)候
如果切換進(jìn)來的是內(nèi)核線程,則置active_mm為切換出去的進(jìn)程的active_mm;
如果切換出去的是內(nèi)核線程,則置active_mm為NULL。
linux在創(chuàng)建用戶任務(wù)的時(shí)候,給每個(gè)任務(wù)都分配了一個(gè)kernel modestack。一個(gè)運(yùn)行在用戶態(tài)的任務(wù)如果被一個(gè)IRQ打斷,中斷處理要做一次堆棧切換。這時(shí)linux好像使用了任務(wù)的kernel modestack,也就是說linux系統(tǒng)中沒有一個(gè)唯一的系統(tǒng)堆棧,而是每一個(gè)任務(wù)都有一個(gè)系統(tǒng)堆棧,中斷處理的棧使用的就是被打斷任務(wù)的系統(tǒng)堆棧。 內(nèi)核線程也是進(jìn)程,只不過沒有自己的用戶空間,但task_struct和內(nèi)核堆棧還是得有的,要不怎么運(yùn)行呢?
[1.內(nèi)核在主動進(jìn)行進(jìn)程調(diào)度時(shí),可以自己設(shè)置將要投入運(yùn)行進(jìn)程的 sp0為TSS段中的sp0,則該用戶進(jìn)程在進(jìn)入內(nèi)核后使用的是它自身的系統(tǒng)堆棧,但如果cpu運(yùn)行在某一用戶進(jìn)程時(shí),而為另一用戶進(jìn)程服務(wù)的外部中斷發(fā) 生了,在進(jìn)入內(nèi)核后使用的是當(dāng)前用戶進(jìn)程的系統(tǒng)堆棧,還是中斷服務(wù)的另一用戶進(jìn)程的系統(tǒng)堆棧呢?
2操作系統(tǒng)映象是否擁有自己的堆棧空間?還是利用用戶進(jìn)程的系統(tǒng)堆棧?
回答: 1。外部中斷不是為某個(gè)用戶進(jìn)程服務(wù)的,是為整個(gè)操作系統(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處理例程共用這個(gè)棧來說似乎有點(diǎn)不夠用,所有引入了 兩個(gè)棧:硬件IRQ棧和軟件IRQ棧。在這種情況下,當(dāng)內(nèi)核進(jìn)入中斷之后,檢測自己所在的棧是內(nèi)核棧還是中斷棧。如果是中斷棧(中斷嵌套情況)就去執(zhí)行中 斷例程;如果是內(nèi)核棧就切換到中斷棧,同時(shí)復(fù)制當(dāng)前內(nèi)核棧中的部分thread_info數(shù)據(jù)到中斷棧。
   但是2.6.36之后的內(nèi)核就不再有4K內(nèi)核棧的配置,對于IA-32統(tǒng)一使用8K內(nèi)核棧,并總是使用兩個(gè)獨(dú)立的8K中斷棧。這樣的改變應(yīng)該是由于計(jì)算機(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è)計(jì)。也就是說:ARM并沒有獨(dú)立的中斷棧,中斷共用當(dāng)前進(jìn)程的內(nèi)核棧。

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

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

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



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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多