退休的贵族进程 0号进程
所有进程的祖先叫做进程0
在系统初始化阶段由start_kernel()函数从无到有手工创建的一个内核线程
进程0最后的初始化工作创建init内核线程,此后运行cpu_idle,成为idle进程
控制权的接力棒从bios-->bootloader-->idle,某种程度上说,就是完成子系统初始化使命后,就退居二线了。
0号进程一直处于皇宫“内核态”,没有出过宫“到用户态”,所谓贵族终身。
0号进程的代码概要图
字画的臭(逃),主要意思是0号进程是这样串行产生的:
start_kernel -->rest_init --> cpu_idle_loop
进入idle loop的堆栈样本如下(堆栈调用图也可以从中画出来的)
(gdb) bt
#0 cpu_idle_loop () at kernel/sched/idle.c:201
#1 cpu_startup_entry (state=<optimized out>) at kernel/sched/idle.c:274
#2 0xc175d22d in rest_init () at init/main.c:418
#3 0xc1a4bb59 in start_kernel () at init/main.c:680
#4 0xc1a4b360 in i386_start_kernel () at arch/x86/kernel/head32.c:49
#5 0x00000000 in ?? ()
idle最核心的代码位置(前方高能,含有chinglish,蹩脚翻译,请大拿指点。只翻译部分主要的)
static void cpu_idle_loop(void)
{
while (1) {
/*如果本架构下面有标示轮询poll的bit位,我们会保持不变??(理解:始终在这个循环里)
如果idle没有被调度,那么poll bit是被清空的
反过来说, 如果 设置了poll bit,那么need_resched将会保证cpu进行重新调度。
*/
__current_set_polling();
tick_nohz_idle_enter();
while (!need_resched()) {
check_pgt_cache();
rmb();
if (cpu_is_offline(smp_processor_id()))
arch_cpu_idle_dead();
local_irq_disable();
arch_cpu_idle_enter();
/*
在poll mode 中,我们会使能中断 和 自旋锁
同时 如果检测到唤醒(来自一些设备广播的),
我们将努力避免进入深度睡眠,因为我们知道 IPI (???)即将马上来到
*/
if (cpu_idle_force_poll || tick_check_broadcast_expired())
cpu_idle_poll();